h264parse bug?: Files unplayable in flash because P Slices before I Slice

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

h264parse bug?: Files unplayable in flash because P Slices before I Slice

Mike Mitchell
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
Reply | Threaded
Open this post in threaded view
|

Re: h264parse bug?: Files unplayable in flash because P Slices before I Slice

Mike Mitchell
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:
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
Reply | Threaded
Open this post in threaded view
|

Re: h264parse bug?: Files unplayable in flash because P Slices before I Slice

Tim-Philipp Müller-2
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
Reply | Threaded
Open this post in threaded view
|

Re: h264parse bug?: Files unplayable in flash because P Slices before I Slice

Mike Mitchell
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?

Thanks.
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:
> 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


_______________________________________________
gstreamer-devel mailing list
[hidden email]
http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Appsink freezing my pipeline

Paul Stuart
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
Reply | Threaded
Open this post in threaded view
|

Re: Appsink freezing my pipeline

Mike Mitchell
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]> 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]
http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel


_______________________________________________
gstreamer-devel mailing list
[hidden email]
http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: Appsink freezing my pipeline

Paul Stuart


Unfortunately neither of those impacted the behavior one way or another.

Thanks for the quick reply!
Paul

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]> 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]
http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel



_______________________________________________
gstreamer-devel mailing list
[hidden email]
http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: Appsink freezing my pipeline

Paul Stuart
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