AW: Dynamically record a h264 stream

Davide Tuccilli tuccio89 at hotmail.com
Tue Mar 22 19:58:37 UTC 2016


On 20/03/2016 10:35, Sebastian Dröge wrote:
> On Sa, 2016-03-19 at 18:11 +0100, Davide Tuccilli wrote:
>> Oh I see, I thought it had the same effect. I've been trying to play
>> around with the capsfilter, from my understanding h264parse does the
>> conversion, so I should do something like queue ! capsfilter
>> caps=video/x-h264,stream-format=avc ! h264parse ! mp4mux ! filesink,
>> but when I do this, the linking between the tee src_%u pad and the
>> queue sink pad fails.
> You will need one h264parse per branch then. Each of them can only
> convert into one stream format, so the one before the tee might convert
> into one that the mp4mux branch does not like.
>
>
>
> _______________________________________________
> gstreamer-devel mailing list
> gstreamer-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
I've been trying a lot of things, and I noticed that I'm actually having 
problems even with a static pipeline that tries to achieve the same 
goal. I'm creating a pipeline like this:

{

     m_recordBin = gst_pipeline_new(nullptr);

     GstElement * v4l2src    = gst_element_factory_make("v4l2src", 
"recsource");
     GstElement * capsFilter = gst_element_factory_make("capsfilter", 
nullptr);
     GstElement * h264parse  = gst_element_factory_make("h264parse", 
nullptr);
     GstElement * mux        = gst_element_factory_make("mp4mux", 
nullptr);   // mpegtsmux, qtmux, mp4mux
     GstElement * muxCaps    = gst_element_factory_make("capsfilter", 
nullptr);
     GstElement * fileSink   = gst_element_factory_make("filesink", 
nullptr);

     g_object_set(G_OBJECT(fileSink), "location", filename, nullptr);
     g_object_set(G_OBJECT(fileSink), "sync", TRUE, nullptr);

     g_object_set(G_OBJECT(v4l2src), "device", "/dev/video1", nullptr);

     GstCaps * caps = gst_caps_new_simple("video/x-h264",
                                          "width", G_TYPE_INT, 720,
                                          "height", G_TYPE_INT, 576,
                                          "framerate", 
GST_TYPE_FRACTION, 25, 1,
                                          nullptr);

     g_object_set(G_OBJECT(capsFilter), "caps", caps, nullptr);

     GstCaps * capsavc = gst_caps_new_simple("video/x-h264",
                                             "stream-format", 
G_TYPE_STRING, "avc",
                                             "alignment", G_TYPE_STRING, 
"au",
                                             nullptr);

     g_object_set(G_OBJECT(muxCaps), "caps", capsavc, nullptr);

     gst_bin_add_many(GST_BIN(m_recordBin), v4l2src, capsFilter, 
h264parse, muxCaps, mux, fileSink, nullptr);

     if (!gst_element_link_many(v4l2src, capsFilter, h264parse, muxCaps, 
mux, fileSink, nullptr)) {
         return false;
     }
     else {
         return true;
     }

}

and the weird part is that some times it works, sometimes it doesn't and 
i get the same broken/invalid nal messages from h264parse

I created a function that iterates over the pads of this pipeline and 
prints the current caps, and when it works the result is like this:

filesink0 sink : video/quicktime, variant=(string)iso
mp4mux0 src : video/quicktime, variant=(string)iso
mp4mux0 video_0 : video/x-h264, stream-format=(string)avc, 
alignment=(string)au, width=(int)720, height=(int)576, 
pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)25/1, 
parsed=(boolean)true, profile=(string)high, level=(string)4, 
codec_data=(buffer)01640028ffe1007267640028ad84054562b8ac5474202a2b15c562a3a1015158ae2b151d080a8ac57158a8e84054562b8ac5474202a2b15c562a3a10248521393c9f27e4fe4fc9f279b9b34d081242909c9e4f93f27f27e4f93cdcd9a6b405a093499000003e80000c350e040007a12000112a8bdef85e1108d401000468ee3c30
capsfilter1 sink : video/x-h264, stream-format=(string)avc, 
alignment=(string)au, width=(int)720, height=(int)576, 
pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)25/1, 
parsed=(boolean)true, profile=(string)high, level=(string)4, 
codec_data=(buffer)01640028ffe1007267640028ad84054562b8ac5474202a2b15c562a3a1015158ae2b151d080a8ac57158a8e84054562b8ac5474202a2b15c562a3a10248521393c9f27e4fe4fc9f279b9b34d081242909c9e4f93f27f27e4f93cdcd9a6b405a093499000003e80000c350e040007a12000112a8bdef85e1108d401000468ee3c30
capsfilter1 src : video/x-h264, stream-format=(string)avc, 
alignment=(string)au, width=(int)720, height=(int)576, 
pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)25/1, 
parsed=(boolean)true, profile=(string)high, level=(string)4, 
codec_data=(buffer)01640028ffe1007267640028ad84054562b8ac5474202a2b15c562a3a1015158ae2b151d080a8ac57158a8e84054562b8ac5474202a2b15c562a3a10248521393c9f27e4fe4fc9f279b9b34d081242909c9e4f93f27f27e4f93cdcd9a6b405a093499000003e80000c350e040007a12000112a8bdef85e1108d401000468ee3c30
h264parse0 sink : video/x-h264, stream-format=(string)byte-stream, 
alignment=(string)au, width=(int)720, height=(int)576, 
pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)25/1
h264parse0 src : video/x-h264, stream-format=(string)avc, 
alignment=(string)au, width=(int)720, height=(int)576, 
pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)25/1, 
parsed=(boolean)true, profile=(string)high, level=(string)4, 
codec_data=(buffer)01640028ffe1007267640028ad84054562b8ac5474202a2b15c562a3a1015158ae2b151d080a8ac57158a8e84054562b8ac5474202a2b15c562a3a10248521393c9f27e4fe4fc9f279b9b34d081242909c9e4f93f27f27e4f93cdcd9a6b405a093499000003e80000c350e040007a12000112a8bdef85e1108d401000468ee3c30
capsfilter0 sink : video/x-h264, stream-format=(string)byte-stream, 
alignment=(string)au, width=(int)720, height=(int)576, 
pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)25/1
capsfilter0 src : video/x-h264, stream-format=(string)byte-stream, 
alignment=(string)au, width=(int)720, height=(int)576, 
pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)25/1
recsource src : video/x-h264, stream-format=(string)byte-stream, 
alignment=(string)au, width=(int)720, height=(int)576, 
pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)25/1

When it doesn't the result is like this:

filesink0 sink : NULL
mp4mux0 src : NULL
mp4mux0 video_0 : NULL
capsfilter1 sink : NULL
capsfilter1 src : NULL
h264parse0 sink : video/x-h264, stream-format=(string)byte-stream, 
alignment=(string)au, width=(int)720, height=(int)576, 
pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)25/1
h264parse0 src : NULL
capsfilter0 sink : video/x-h264, stream-format=(string)byte-stream, 
alignment=(string)au, width=(int)720, height=(int)576, 
pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)25/1
capsfilter0 src : video/x-h264, stream-format=(string)byte-stream, 
alignment=(string)au, width=(int)720, height=(int)576, 
pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)25/1
recsource src : video/x-h264, stream-format=(string)byte-stream, 
alignment=(string)au, width=(int)720, height=(int)576, 
pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)25/1

Any reason the current caps might result null for the muxer 
video_0/h264parse src pads? For what I understand, that's the problem 
right? I should have stream-format=avc there. I'm not sure how to debug 
this.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/gstreamer-devel/attachments/20160322/412c3fe7/attachment-0001.html>


More information about the gstreamer-devel mailing list