diff mbox

[FFmpeg-devel,1/2] svq1dec: Ensure that pixel format constraints are respected

Message ID 20180717193919.99925-1-vittorio.giovara@gmail.com
State New
Headers show

Commit Message

Vittorio Giovara July 17, 2018, 7:39 p.m. UTC
YUV410P requires that sizes are divisible by 4. There seem to be
some encoders that ignore that and encode a different value in
the bitstream itself. Handle that case by exporting the relative
cropping information.
---
Alternatively it is possible to always enforce mod4 sizes and call
it a day.
Vittorio

 libavcodec/svq1dec.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

Comments

Carl Eugen Hoyos July 17, 2018, 9:38 p.m. UTC | #1
2018-07-17 21:39 GMT+02:00, Vittorio Giovara <vittorio.giovara@gmail.com>:
> YUV410P requires that sizes are divisible by 4. There seem to be
> some encoders that ignore that and encode a different value in
> the bitstream itself. Handle that case by exporting the relative
> cropping information.

Can you provide a sample?

Thank you, Carl Eugen
Vittorio Giovara July 18, 2018, 1:54 p.m. UTC | #2
2018-07-17 21:39 GMT+02:00, Carl Eugen Hoyos <ceffmpeg at gmail.com>:
> 2018-07-17 21:39 GMT+02:00, Vittorio Giovara <vittorio.giovara at gmail.com>:
> > YUV410P requires that sizes are divisible by 4. There seem to be
> > some encoders that ignore that and encode a different value in
> > the bitstream itself. Handle that case by exporting the relative
> > cropping information.
>
>Can you provide a sample?
>
>Thank you, Carl Eugen

It is possible to generate samples affected by this bug with the svq1 or
ffv1 encoders, like this:

./ffmpeg -f lavfi -i testsrc -s 190x240 -t 1 -pix_fmt yuv410p -c:v ffv1 output-yuv410p.avi

A prime example where the generated sample will fail is with a strict
scaler, such as zimg:

./ffmpeg -i output-yuv410p.avi -vf zscale -f null -

which will fail with

code 1027: image dimensions must be divisible by subsampling factor
Error while filtering: Generic error in an external library
Failed to inject frame into filter network: Generic error in an external library
Error while processing the decoded data for stream #0:0


While the proposed patch won't directly fix the issue with zscale, it will
offer tools for API users to adjust sizes accrodingly, and avoid it
altoether.

Regards,
    Vittorio
diff mbox

Patch

diff --git a/libavcodec/svq1dec.c b/libavcodec/svq1dec.c
index d3e60c3a4a..55047b43ce 100644
--- a/libavcodec/svq1dec.c
+++ b/libavcodec/svq1dec.c
@@ -663,7 +663,8 @@  static int svq1_decode_frame(AVCodecContext *avctx, void *data,
         return result;
     }
 
-    result = ff_set_dimensions(avctx, s->width, s->height);
+    /* sizes must be always disivible by 4 due to pixel format constraints */
+    result = ff_set_dimensions(avctx, FFALIGN(s->width, 4), FFALIGN(s->height, 4));
     if (result < 0)
         return result;
 
@@ -755,6 +756,11 @@  static int svq1_decode_frame(AVCodecContext *avctx, void *data,
     *got_frame = 1;
     result     = buf_size;
 
+    cur->crop_left   = 0;
+    cur->crop_top    = 0;
+    cur->crop_right  = FFALIGN(s->width,  4) - s->width;
+    cur->crop_bottom = FFALIGN(s->height, 4) - s->height;
+
 err:
     av_free(pmv);
     return result;
@@ -843,6 +849,7 @@  AVCodec ff_svq1_decoder = {
     .close          = svq1_decode_end,
     .decode         = svq1_decode_frame,
     .capabilities   = AV_CODEC_CAP_DR1,
+    .caps_internal  = FF_CODEC_CAP_EXPORTS_CROPPING,
     .flush          = svq1_flush,
     .pix_fmts       = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV410P,
                                                      AV_PIX_FMT_NONE },