[FFmpeg-devel] [PATCH] nvenc: Compensate for hardware trying to mess with aspect ratio of DVD content.

Agatha Hu ahu at nvidia.com
Wed Jan 21 07:17:09 CET 2015


On 2015/1/18 4:01, Philip Langdale wrote:
> There is a long sad story behind all this, but it's somewhat ambiguous as to
> whether DVD content should be treated as 720 pixels wide or 704 pixels, with
> 16 pixels cut off. If you decide is should be 704 pixels wide, you need to
> adjust the sample aspect ratio to keep the final display aspect ratio correct.
>
> For reasons we are not privy too, nvidia decided that the nvenc encoder should
> apply this aspect correction, whether you want it to or not. (I guess there
> might be a flag for it, but if there is it's not documented). So, if you want
> to transcode DVD content at the original size, you need to adjust the aspect
> ratio information you pass to the encoder to compensate for their 'correction'.
>
> This 'correction' is only applied to 720x480 and 720x576 content - and it does
> so regardless of the input aspect ratio.
> ---
>   libavcodec/nvenc.c | 12 ++++++++++++
>   1 file changed, 12 insertions(+)
>
> diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
> index efa3f04..8a0d584 100644
> --- a/libavcodec/nvenc.c
> +++ b/libavcodec/nvenc.c
> @@ -587,6 +587,18 @@ static av_cold int nvenc_encode_init(AVCodecContext *avctx)
>           ctx->init_encode_params.darWidth = avctx->width;
>       }
>
> +    // De-compensate for hardware, dubiously, trying to compensate for
> +    // playback at 704 pixel width.
> +    if (avctx->width == 720 &&
> +        (avctx->height == 480 || avctx->height == 576)) {
> +        av_reduce(&dw, &dh,
> +                  ctx->init_encode_params.darWidth * 44,
> +                  ctx->init_encode_params.darHeight * 45,
> +                  1024 * 1204);
> +        ctx->init_encode_params.darHeight = dh;
> +        ctx->init_encode_params.darWidth = dw;
> +    }
> +
>       ctx->init_encode_params.frameRateNum = avctx->time_base.den;
>       ctx->init_encode_params.frameRateDen = avctx->time_base.num * avctx->ticks_per_frame;
>
>

Here's the reply from NVENC engineers
It is not same thing as SAR. It is the display aspect ratio i.e 
width/height = DAR/SAR

The calculation below should be like

If (avctx->sample_aspect_ratio.num > 0  && 
avctx->sample_aspect_ratio.den > 0 )
     av_reduce(&dw, &dh, avctx->sample_aspect_ratio.num * avctx->width, 
avctx->sample_aspect_ratio.den * avctx->height, INT_MAX);

else
     av_reduce(&dw, &dh, avctx->width,  avctx->height, INT_MAX);

ctx->init_encode_params.darHeight = dw;
ctx->init_encode_params.darWidth = dh;

Agatha Hu


More information about the ffmpeg-devel mailing list