I'm experimenting with the videomixer and videomixer2 elements, and having very good luck with them when using live streams. I want to add file-based streams into the mix, and have them either repeat or disappear upon completion.
Repeating a single stream is relatively easy. We can listen for the EOS event on the bus callback and seek to the beginning when the event arrives: =====================================================================
gboolean bus_cb (GstBus *bus, GstMessage *message, gpointer data) { ... switch (GST_MESSAGE_TYPE (message)) { ...
case GST_MESSAGE_EOS: if (!gst_element_seek_simple (GST_ELEMENT(pipeline), GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT, 1)) {
g_warning ("Failed to Return to Beginning of Stream\n");
} break;
... ===================================================================== Works fine, but the "src" in the "message" variable seems to originate from the pipeline, and not any of the elements linked to the filesrc. So with this approach I seem to be tied to seeking on the entire pipeline instead of a subelement.
The next approach I tried was to create a new element "infinitestream". I figured maybe I could trap the EOS event in this element and seek to the beginning for just a filesrc, like so:
gst-launch videomixer2 name=mix sink_0::zorder=1 sink_1::zorder=0 ! ffmpegcolorspace ! video/x-raw-rgb ! ximagesink sync=false filesrc location=videofile.mp4 ! decodebin2 ! identity sync=true ! infinitestream ! ffmpegcolorspace ! video/x-raw-yuv ! mix. videotestsrc pattern=snow is-live=TRUE ! mix.
This comes close, with the stream successfully repeating and playing at the correct rate, but the live pads in the mixer become frozen. Here is the relevant code in "infinitestream":
===================================================================== static void gst_infinite_stream_class_init (GstInfiniteStreamClass * klass) { ...
GST_BASE_TRANSFORM_CLASS (klass)->event = GST_DEBUG_FUNCPTR (gst_infinitestream_sink_eventfunc); ... } ... static gboolean
gst_infinitestream_sink_eventfunc (GstBaseTransform * trans, GstEvent * event) { if(event->type != GST_EVENT_EOS) { return TRUE;
} if (!gst_element_seek_simple (GST_ELEMENT(trans), GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT, 1)) { g_warning ("Infinite Loop Failed to Return to Beginning of Stream\n");
} return FALSE; } ===================================================================== Could anyone comment on this approach? Is there anything I can do out-of-the-box to implement this behavior, or would a change to the gstreamer source be necessary? I'd be happy to investigate such a change if anyone can point me in the right direction.
_______________________________________________ gstreamer-devel mailing list [hidden email] http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Free forum by Nabble | Edit this page |