After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 796900 - avdec: loses the last (num_cores + 1) frames
avdec: loses the last (num_cores + 1) frames
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gst-libav
git master
Other Linux
: Normal blocker
: 1.15.1
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2018-07-31 15:48 UTC by Alicia Boya García
Modified: 2018-07-31 18:55 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
decoders: fix draining (3.06 KB, patch)
2018-07-31 16:35 UTC, Mathieu Duponchelle
committed Details | Review

Description Alicia Boya García 2018-07-31 15:48:11 UTC
How to reproduce:

1. Update to the latest master. The problem reproduces with ffmpeg 4.0.

2. Create a test file with 3 + (num_cores + 1) frames:

NUM_CORES=$(getconf _NPROCESSORS_ONLN)
gst-launch-1.0 videotestsrc num-buffers=$((3 + ($NUM_CORES + 1))) ! video/x-raw, framerate=1/1 ! timeoverlay font-desc="Monospace, 64" ! x264enc ! qtmux ! filesink location=/tmp/movie.mp4

3. Play it with gst-play-1.0 or any other GStreamer based player in the same machine, making sure that avdec_h264 is being used as decoder.

Expected result:

`3 + (num_cores + 1)` frames should be played, during `3 + (num_cores + 1)` seconds.

Actual result:

Only the first 3 frames are emited by avdec_h264. Then the playback ends. If a file with only `(num_cores + 1)` or fewer frames is open, playback fails completely.

This can also be checked with gst-launch:

$ gst-launch-1.0 -v filesrc location=/tmp/movie.mp4 ! qtdemux ! avdec_h264 ! fakesink silent=false | grep -c chain
3

It can also be reproduced in a single pipeline if desired:

$ gst-launch-1.0 -v videotestsrc num-buffers=$((3 + ($NUM_CORES + 1))) \
  ! video/x-raw, framerate=1/1 ! timeoverlay font-desc="Monospace, 64" \
  ! x264enc ! avdec_h264 ! fakesink silent=false | grep -c chain
3
Comment 1 Thibault Saunier 2018-07-31 15:51:32 UTC
I have the impression that it is a regression from the ffmpeg 4.X port. I am also gonna add smoke tests in GstValidate for those cases fwiw.
Comment 2 Mathieu Duponchelle 2018-07-31 16:35:58 UTC
Created attachment 373230 [details] [review]
decoders: fix draining
Comment 3 Mathieu Duponchelle 2018-07-31 16:37:01 UTC
Sorry about that, it was a pretty trivial mistake. With this patch, both the audio and video decoders are now adequately drained.
Comment 4 Thibault Saunier 2018-07-31 16:40:58 UTC
Review of attachment 373230 [details] [review]:

::: ext/libav/gstavviddec.c
@@ +1723,3 @@
       got_frame = gst_ffmpegviddec_frame (ffmpegdec, NULL, &ret);
     } while (got_frame && ret == GST_FLOW_OK);
+    avcodec_flush_buffers (ffmpegdec->context);

Why do you flush here now?

@@ +1731,3 @@
+send_packet_failed:
+  GST_WARNING_OBJECT (ffmpegdec, "send packet failed, could not drain decoder");
+  goto done;

Shouldn't it report an error here indeed?
Comment 5 Mathieu Duponchelle 2018-07-31 16:49:50 UTC
(In reply to Thibault Saunier from comment #4)
> Review of attachment 373230 [details] [review] [review]:
> 
> ::: ext/libav/gstavviddec.c
> @@ +1723,3 @@
>        got_frame = gst_ffmpegviddec_frame (ffmpegdec, NULL, &ret);
>      } while (got_frame && ret == GST_FLOW_OK);
> +    avcodec_flush_buffers (ffmpegdec->context);
> 
> Why do you flush here now?

Because that was missing, the call to flush_buffers makes it so the decoder is ready to decode again.

> 
> @@ +1731,3 @@
> +send_packet_failed:
> +  GST_WARNING_OBJECT (ffmpegdec, "send packet failed, could not drain
> decoder");
> +  goto done;
> 
> Shouldn't it report an error here indeed?


No, as you know we don't want to error out at the first problem in the decoders / encoders, it should be translated to GST_AUDIO_DECODER_ERROR along with the rest of the error handling code, but that's a separate issue.
Comment 6 Thibault Saunier 2018-07-31 17:00:17 UTC
Review of attachment 373230 [details] [review]:

(In reply to Mathieu Duponchelle from comment #5)
> (In reply to Thibault Saunier from comment #4)
> > Review of attachment 373230 [details] [review] [review] [review]:
> > 
> > ::: ext/libav/gstavviddec.c
> > @@ +1723,3 @@
> >        got_frame = gst_ffmpegviddec_frame (ffmpegdec, NULL, &ret);
> >      } while (got_frame && ret == GST_FLOW_OK);
> > +    avcodec_flush_buffers (ffmpegdec->context);
> > 
> > Why do you flush here now?
> 
> Because that was missing, the call to flush_buffers makes it so the decoder
> is ready to decode again.

Indeed, makes sense, and it was there for the audio decoder.
 
> > @@ +1731,3 @@
> > +send_packet_failed:
> > +  GST_WARNING_OBJECT (ffmpegdec, "send packet failed, could not drain
> > decoder");
> > +  goto done;
> > 
> > Shouldn't it report an error here indeed?
> 
> 
> No, as you know we don't want to error out at the first problem in the
> decoders / encoders, it should be translated to GST_AUDIO_DECODER_ERROR
> along with the rest of the error handling code, but that's a separate issue.

Right, got it.
Comment 7 Mathieu Duponchelle 2018-07-31 17:13:49 UTC
Attachment 373230 [details] pushed as ff3a8f6 - decoders: fix draining
Comment 8 Mathieu Duponchelle 2018-07-31 17:14:40 UTC
Thanks for catching that btw Alicia!
Comment 9 Alicia Boya García 2018-07-31 18:55:45 UTC
The patch fixes indeed the issue, thanks for the fix!