Videos I record from an IP camera with h264 using rtp to mp4mux are slightly corrupted: 1. On flash players like jwplayer or flowplayer, they play but with no video. 2. On native players like vlc, mplayer, They play but do start poorly with a gray screen until the first Iframe comes through.
My best clue is that VLC, ffmpeg and tcprobe all report: "Missing reference picture decode_slice_header error". This seems to be related to the fact that the h264 stream contains several P Slices before it contains the first I slice. Some players just ignore this, but to flash it seems to ruin the whole stream.
Since I'm forced to accept flash for compatibility reasons, and really want to avoid transcoding everything, I'd like to fix the file by cleaning up these useless P Slices at the front of the stream.
Can anyone suggest a gstreamer element that could do drop P Slices until the first I Slice? Or do I need to code this myself.... If I were going to add this functionality, is h264parse the correct place to do it?
Mike Mitchell _______________________________________________ gstreamer-devel mailing list [hidden email] http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Turns out leading P frames were not the only problem with my stream. But I would still like an architect's opinion, shouldn't h264parse ensure the stream is spec compliant? I've read the source and see there is some logic to detect the I frame, but it does not appear to trash the P frames until the I frames start like I would expect.
Mike Mitchell On Tue, Oct 4, 2011 at 2:26 PM, Mike Mitchell <[hidden email]> wrote:
_______________________________________________ gstreamer-devel mailing list [hidden email] http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
On Fri, 2011-10-07 at 01:42 -0700, Mike Mitchell wrote:
> Turns out leading P frames were not the only problem with my stream. > But I would still like an architect's opinion, shouldn't h264parse > ensure the stream is spec compliant? I've read the source and see > there is some logic to detect the I frame, but it does not appear to > trash the P frames until the I frames start like I would expect. Yes, I believe there are one or two open bugs about that as well. https://bugzilla.gnome.org/show_bug.cgi?id=659489 and https://bugzilla.gnome.org/show_bug.cgi?id=646327 look related. Cheers -Tim _______________________________________________ gstreamer-devel mailing list [hidden email] http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Tim, Thanks for pointing these out. Reading them it seems a patch has been proposed that may work for me in addition to closing these 2 bugs. I will try it and report my results. This patch was submitted in March. But it seems not everyone is OK with it dropping some data. The submitter seems to have done what was asked of him here: http://gstreamer.freedesktop.org/dev/, yet seven months later it remains open.
What is the political process of getting Developer agreement and making the fix in the head? Mike Mitchell On Fri, Oct 7, 2011 at 3:19 AM, Tim-Philipp Müller <[hidden email]> wrote: On Fri, 2011-10-07 at 01:42 -0700, Mike Mitchell wrote: _______________________________________________ gstreamer-devel mailing list [hidden email] http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
In reply to this post by Tim-Philipp Müller-2
Hi,
I have a pipeline (defined in code) that looks roughly like: v4l2src---queue--tee--display | --queue--appsink So, basically tee'ing off the stream after the video source to split it between the display and the appsink. I have set appsink to drop buffers after the maximum number of queued buffers is met. If I replace appsink with fakesink, my pipeline runs fine, but when I use appsink, I get a frame through to the display and then the whole thing freezes. Would one expect this to work? Maybe I am missing some fundamental understanding of tee's and appsink. Thanks, Paul _______________________________________________ gstreamer-devel mailing list [hidden email] http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Perhaps each branch of the Tee should have a queue like below. You might also consider the sync=false on your display.
| --queue--appsink Mike Mitchell
On Fri, Oct 7, 2011 at 11:35 AM, Paul Stuart <[hidden email]> wrote: Hi, _______________________________________________ gstreamer-devel mailing list [hidden email] http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Unfortunately neither of those impacted the behavior one way or another. Thanks for the quick reply! Paul Mike Mitchell wrote:
_______________________________________________ gstreamer-devel mailing list [hidden email] http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
In reply to this post by Mike Mitchell
Hi,
Still stuck on the same problem with appsink freezing my pipeline. If I replace appsink with fakesink in the code below, it runs fine. If I leave it as appsink, I get a frame out to my display and then everything freezes. I'm posting a snippet of my code below, maybe I'm doing something goofy? The premise is that I've got a pipeline with a tee, one path off the tee goes to the display, and the other tee goes to my JPEG capture. Code for the JPEG capture bin with the appsink is below. Any suggestions would be greatly appreciated. void GStreamerJpegBin::makeLink(GstElement *pipeline, GstElement *videoSrcTee){ GstElement *queue; GstPadLinkReturn retVal; GstPad *sinkpadvideo, *srcpadvideo; gchar *name; /* first thing we want to do is add an appsink to the tee off of our video source, and later we will build up a pipeline to capture a single JPEG image */ // create new bin to stuff our queue and appsink into appSinkBin = gst_bin_new (NULL); queue = gst_element_factory_make ("queue", NULL); appSink = gst_element_factory_make ("appsink", NULL); // only allow three frames to queue up at a time in our appsink APPSINK_MAX_BUFFERS = 3 gst_app_sink_set_max_buffers (GST_APP_SINK(appSink), APPSINK_MAX_BUFFERS); gst_app_sink_set_drop (GST_APP_SINK(appSink), true); // make queue leaky g_object_set(G_OBJECT(queue), "leaky", 2, NULL); // test for existence if (NULL == queue) g_error ("Couldn't create a queue\n"); if (NULL == appSink) g_error ("Couldn't create an appsink\n"); // add them into the bin gst_bin_add_many(GST_BIN(appSinkBin), queue, appSink, NULL); // link the internals of the appSinkBin if(gst_element_link(queue, appSink)){ printf("MADE LINK FROM QUEUE TO APPSINK\n"); }else { printf("LINK FROM QUEUE TO APPSINK FAILED\n"); } // get a new src pad from the tee element srcpadvideo = gst_element_get_request_pad (videoSrcTee, "src%d"); name = gst_pad_get_name (srcpadvideo); g_print ("DEBUG: A new pad %s was created\n", name); g_free (name); // get the sink pad on our queue sinkpadvideo = gst_element_get_static_pad(queue, "sink"); // create a ghost pad on the bin to link the queue sink pad to the bin sink pad gst_element_add_pad(appSinkBin, gst_ghost_pad_new("videosink", sinkpadvideo)); // we can unref our copy now that it has been added gst_object_unref(GST_OBJECT(sinkpadvideo)); // set the new bin to PLAYING (not sure if I need to do this) //gst_element_set_state(appSinkBin, GST_STATE_PLAYING); // add the bin into our pipeline gst_bin_add(GST_BIN(pipeline), appSinkBin); // Link src pad of tees to sink pads of bin with filtered caps GstCaps *capsFilter = gst_caps_new_simple ("video/x-raw-yuv", "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('N', 'V', '1', '2'), "width", G_TYPE_INT, 736, "height", G_TYPE_INT, 480, NULL); sinkpadvideo = gst_element_get_pad(appSinkBin, "videosink"); retVal = gst_pad_link(srcpadvideo, sinkpadvideo); gst_caps_unref (capsFilter); if(0 == retVal){ g_print("DEBUG: MADE LINK FROM TEE TO APP SINK BIN\n"); }else { g_print("DEBUG: LINK FROM TEE TO APP SINK BIN FAILED: %d\n", retVal); } // change state of main pipeline to playing //gst_element_set_state (pipeline, GST_STATE_PLAYING); gst_object_unref(GST_OBJECT(sinkpadvideo)); gst_object_unref(GST_OBJECT(srcpadvideo)); // store some elements for use in our glib callbacks JpegCapMgr.appSink = appSink; JpegCapMgr.mainPipeline = pipeline; //createJpegEncPipeline(); } Mike Mitchell wrote: > Perhaps each branch of the Tee should have a queue like below. You > might also consider the sync=false on your display. > > v4l2src--tee--queue--display > | > --queue--appsink > * > * > *Mike Mitchell* > > > On Fri, Oct 7, 2011 at 11:35 AM, Paul Stuart <[hidden email] > <mailto:[hidden email]>> wrote: > > Hi, > I have a pipeline (defined in code) that looks roughly like: > > v4l2src---queue--tee--display > | > --queue--appsink > > So, basically tee'ing off the stream after the video source to > split it between the display and the appsink. > > I have set appsink to drop buffers after the maximum number of > queued buffers is met. > > If I replace appsink with fakesink, my pipeline runs fine, but > when I use appsink, I get a frame through to the display and then > the whole thing freezes. > > Would one expect this to work? Maybe I am missing some fundamental > understanding of tee's and appsink. > > Thanks, > Paul > > > > _______________________________________________ > gstreamer-devel mailing list > [hidden email] > <mailto:[hidden email]> > http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel > > _______________________________________________ gstreamer-devel mailing list [hidden email] http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Free forum by Nabble | Edit this page |