[libcamera-devel] [PATCH] gstreamer: Implement EOS handling

Jaslo Ziska jaslo at ziska.de
Thu Nov 9 15:20:22 CET 2023


Hi Kieran,

Kieran Bingham <kieran.bingham at ideasonboard.com> writes:
> Quoting Jaslo Ziska via libcamera-devel (2023-11-09 12:51:15)
>> Hi,
>>
>> Umang Jain <umang.jain at ideasonboard.com> writes:
>> > Hi Jalso
>> >
>> > On 11/6/23 10:22 PM, Jaslo Ziska via libcamera-devel wrote:
>> >> ---
>> >> Hi,
>> >>
>> >> I recently implemented basic EOS handling for the 
>> >> libcamerasrc
>> >> gstreamer element.
>> >
>> > Ah thanks, I remember we do track a bug report here:
>> > https://bugs.libcamera.org/show_bug.cgi?id=91
>>
>> Ah yes, I remember that I stumbled upon this when I was first
>> investigating this, I will update the bug report.
>>
>> >>
>> >> I basically looked at how GstBaseSrc does it and tried to do 
>> >> it
>> >> similarly.
>> >>
>> >> I have no idea whether the locking is correct or if this is
>> >> thread safe but so far it worked without any issues for my
>> >> purposes.
>> >>
>> >> You can also now run the following command and receive a
>> >> working video file:
>> >>
>> >> gst-launch-1.0 -e libcamerasrc ! videoconvert ! x264enc !
>> >> h264parse ! mp4mux ! filesink location=test.mp4
>> >
>> > Good to see that the diff is tested :-D
>>
>> Speaking of testing, I just ran the test suite and, except for 
>> the
>> multi_stream_test (which was skipped) the other tests 
>> succeeded.
>>
>> >>
>> >> Looking forward for feedback!
>> >
>> > It looks logical and on the right track to me atleast. But 
>> > there
>> > might be other implications regarding the threading and
>> > locking mechanisms.
>>
>> Thanks! That is what I worry about too, maybe someone can 
>> review
>> this.
>>
>> >> Cheers,
>> >>
>> >> Jaslo
>> >>
>> >>   src/gstreamer/gstlibcamerasrc.cpp | 47
>> >>   +++++++++++++++++++++++++++++++
>> >>   1 file changed, 47 insertions(+)
>> >>
>> >> diff --git a/src/gstreamer/gstlibcamerasrc.cpp
>> >> b/src/gstreamer/gstlibcamerasrc.cpp
>> >> index 63d99571..a4681e1e 100644
>> >> --- a/src/gstreamer/gstlibcamerasrc.cpp
>> >> +++ b/src/gstreamer/gstlibcamerasrc.cpp
>> >> @@ -144,6 +144,9 @@ struct _GstLibcameraSrc {
>> >>      gchar *camera_name;
>> >>      controls::AfModeEnum auto_focus_mode =
>> >>   controls::AfModeManual;
>> >>
>> >> +    GstEvent *pending_eos;
>> >> +    int has_pending_eos;
>> >> +
>> >>      GstLibcameraSrcState *state;
>> >>      GstLibcameraAllocator *allocator;
>> >>      GstFlowCombiner *flow_combiner;
>> >> @@ -397,6 +400,21 @@ gst_libcamera_src_task_run(gpointer
>> >> user_data)
>> >>
>> >>      bool doResume = false;
>> >>
>> >> +    if (g_atomic_int_get(&self->has_pending_eos)) {
>> >> +            g_atomic_int_set(&self->has_pending_eos, 
>> >> FALSE);
>> >> +
>> >> +            GST_OBJECT_LOCK(self);
>> >> +            GstEvent *event = self->pending_eos;
>> >> +            self->pending_eos = NULL;
>> >> +            GST_OBJECT_UNLOCK(self);
>> >> +
>> >> +            for (GstPad *srcpad : state->srcpads_)
>> >> +                    gst_pad_push_event(srcpad, 
>> >> gst_event_ref(event));
>> >> +            gst_event_unref(event);
>> >> +
>> >> +            return;
>> >> +    }
>> >> +
>> >>      /*
>> >>       * Create and queue one request. If no buffers are
>> >>   available the
>> >>       * function returns -ENOBUFS, which we ignore here as
>> >>   that's not a
>> >> @@ -747,6 +765,32 @@ 
>> >> gst_libcamera_src_change_state(GstElement
>> >> *element, GstStateChange transition)
>> >>      return ret;
>> >>   }
>> >>
>> >> +static gboolean
>> >> +gst_libcamera_src_send_event(GstElement *element, GstEvent
>> >> *event)
>> >> +{
>> >> +    GstLibcameraSrc *self = GST_LIBCAMERA_SRC(element);
>> >> +    gboolean ret = FALSE;
>> >> +
>> >> +    switch (GST_EVENT_TYPE(event)) {
>> >> +    case GST_EVENT_EOS: {
>> >> +            GST_OBJECT_LOCK(self);
>> >> +            g_atomic_int_set(&self->has_pending_eos, TRUE);
>> >> +            if (self->pending_eos)
>> >> +                    gst_event_unref(self->pending_eos);
>> >> +            self->pending_eos = event;
>> >> +            GST_OBJECT_UNLOCK(self);
>> >> +
>> >> +            ret = TRUE;
>> >> +            break;
>> >> +    }
>> >> +    default:
>> >> +            gst_event_unref(event);
>> >> +            break;
>> >> +    }
>> >> +
>> >> +    return ret;
>> >> +}
>> >> +
>> >>   static void
>> >>   gst_libcamera_src_finalize(GObject *object)
>> >>   {
>> >> @@ -779,6 +823,8 @@ gst_libcamera_src_init(GstLibcameraSrc
>> >> *self)
>> >>      state->srcpads_.push_back(gst_pad_new_from_template(templ,
>> >>   "src"));
>> >>      gst_element_add_pad(GST_ELEMENT(self),
>> >>   state->srcpads_.back());
>> >>
>> >> +    GST_OBJECT_FLAG_SET(self, GST_ELEMENT_FLAG_SOURCE);
>> >> +
>> >
>> > I always thought libcamerasrc was inheriting from GstBaseSrc,
>> > but in fact it's not.
>> > So, setting the GST_ELEMENT_FLAG_SOURCE makes sense here.
>>
>> This flag is actually required to receive the eos signal when 
>> it
>> is send to the pipeline bin and not the element directly. Took 
>> me
>> a while to figure out.
>>
>> > Apart from a missing commit mesasge, the patch looks good to 
>> > me.
>> > I'll put this on my radar soon for testing it
>> > rigorously.
>>
>> Oh yeah, a commit message would indeed be nice, completely 
>> forgot
>> that, thanks :)
>
> Can you also add/clarify /how/ the EOS event is being sent in 
> the commit
> message please?

Sure, do you mean I should describe how the libcamerasrc element 
receives the EOS event from the pipeline or how the element is 
sending the event to its pads (or both)?

Also should I create a new patch with only the new commit message 
right now or wait for some actual changes?

>
> Is this issue occuring when you run the pipeline and press 
> ctrl-c for
> instance? or is there some other detail?

Yes, exactly, this is what is being fixed, as gst-launch-1.0 sends 
the EOS event to the pipeline bin and the bin apparently looks for 
the GST_ELEMENT_FLAG_SOURCE flag on an element which than receives 
the EOS event.

Regards,

Jaslo


More information about the libcamera-devel mailing list