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 732631 - Missing frames when encoding 16x16 video to MPEG4/MPEG2/H264
Missing frames when encoding 16x16 video to MPEG4/MPEG2/H264
Status: RESOLVED OBSOLETE
Product: GStreamer
Classification: Platform
Component: gst-libav
git master
Other All
: Normal normal
: git master
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on: 732351
Blocks:
 
 
Reported: 2014-07-02 14:52 UTC by Vincent Penquerc'h
Modified: 2018-11-03 12:56 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Vincent Penquerc'h 2014-07-02 14:52:53 UTC
+++ This bug was initially created as a clone of Bug #732351 +++

When encoding 16x16 video to MPEG, a sanity check triggers in ffmpeg, which causes frames to be not encoded.

To reproduce:
1) Create a 16x16 h264 file:
gst-launch-1.0 videotestsrc pattern=6 num-buffers=1000 ! \
"video/x-raw, format=(string)I420, width=(int)16, height=(int)16, \
framerate=(fraction)1/1" ! x264enc ! qtmux ! filesink location=/tmp/test.mov

2) Play this file:
gst-launch-1.0 playbin uri="file:///tmp/test.mov" video-sink=xvimagesink

3) See grey output, instead of the solid blue (pattern 6) we expected.


Tracing shows the encoding earlies out in libav from a sanity check on size (which is apparently too strict):

gst-libs/ext/libav/libavcodec/mpegvideo_enc.c, function encode_thread:

            if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < MAX_MB_BYTES){
                av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
                return -1;
            }

Commenting out the return -1 above fixes the issue (albeit at the likely cost of possible buffer overflow).
Comment 1 Nicolas Dufresne (ndufresne) 2014-07-02 14:59:28 UTC
in 1) did you mean avenc_mpeg2video instead of x264enc ? Also, do you have the same issue with mpeg2enc ?
Comment 2 Vincent Penquerc'h 2014-07-02 15:08:36 UTC
No, and no. And it also happens with avenc_mpeg4.
Comment 3 Vincent Penquerc'h 2014-07-02 15:28:01 UTC
Actually, this is not quite the same for h264 and mpeg4. I was tracing using mpeg4 after checking what combinations had the issue, and h264 does not trigger that check (but might trigger a similar one elsewhere). Just to be precise.
Comment 4 Nicolas Dufresne (ndufresne) 2014-07-02 15:43:50 UTC
ok, make more sense, comment 1 is a little confusing. I can also reproduce here, notice that the missing frame is also visible when playing back the mov using mplayer.
Comment 5 Vincent Penquerc'h 2014-07-02 16:30:04 UTC
At least for MPEG4, it seems that there is exactly as much space in the s->pb bitbuffer as the maximum size of a MB (which is presumably 16x16). The first loop shows there is something already in that buffer, so there is no space left for the theoretical max size of the only MB to write.

When encoding a frame with more than 1 MB, I think the actual encoded size of the first MB is less than max-mb-size minus whatever was there in the s->pb buffer before starting encoding MBs, so the check never triggers. However, it would likely trigger if all the MBs before the last one were somehow encoded at the max size.

So, to fix this, I think we need to figure out the max amount of data that can be written in s->pb before starting encoding MBs (probably some kind of frame header), and ensure s->pb is initialized with that much space extra.
Comment 6 Vincent Penquerc'h 2014-07-03 12:05:18 UTC
According to http://dvd.sourceforge.net/dvdinfo/mpeghdrs.html, it seems the picture header can be not only variable size, but of any size (at least if crafted):

> additionally if the next bit is "1" (extra_bit_picture) it is followed by 8
> bits of "extra" data (discarded by decoders). This continues until a "0" bit
> is encountered. 

So for at least one case, we can't seem to have a high bound on the amount of data that's present in the buffer prior to encoding a MB.

A middle ground would be to allocate some reasonably sized extra space that should be enough in most cases (hopefully all reasonable ones). In the case of such very large picture headers, encoding would still fail as it does now, but cases like that 16x16 frame would pass.

Opinions ?
Comment 7 GStreamer system administrator 2018-11-03 12:56:38 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/gstreamer/gst-libav/issues/15.