[FFmpeg-devel,2/2] lavc/vaapi_encode: fix the mismatched vbvBuf size unit for mpeg2

Submitted by Linjie Fu on Jan. 16, 2019, 2:34 p.m.

Details

Message ID 20190116143445.9866-1-linjie.fu@intel.com
State New
Headers show

Commit Message

Linjie Fu Jan. 16, 2019, 2:34 p.m.
hrd_buffer_size and hrd_initial_buffer_fullness are set in bits, while
driver takes the vbvBuf size in 16 kbits. The mismatch will cause
quality issue.

One way to solve this issue in FFmpeg level is set the bufsize
specially for mpeg2 as the unit of 16 kbits, and discard the default
CBR mode in driver.

Fix the quality issue in #7650.

Signed-off-by: Linjie Fu <linjie.fu@intel.com>
---
 libavcodec/vaapi_encode.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

Comments

Mark Thompson Jan. 23, 2019, 11:37 p.m.
On 16/01/2019 14:34, Linjie Fu wrote:
> hrd_buffer_size and hrd_initial_buffer_fullness are set in bits, while
> driver takes the vbvBuf size in 16 kbits. The mismatch will cause
> quality issue.
> 
> One way to solve this issue in FFmpeg level is set the bufsize
> specially for mpeg2 as the unit of 16 kbits, and discard the default
> CBR mode in driver.
> 
> Fix the quality issue in #7650.
> 
> Signed-off-by: Linjie Fu <linjie.fu@intel.com>
> ---
>  libavcodec/vaapi_encode.c | 8 +++++---
>  1 file changed, 5 insertions(+), 3 deletions(-)

The documentation is very clear that these values are all in bits - <https://github.com/intel/libva/blob/master/va/va.h#L2095-L2100>.

Sounds like a driver bug?

- Mark
Linjie Fu Jan. 24, 2019, 1:26 a.m.
> -----Original Message-----

> From: ffmpeg-devel [mailto:ffmpeg-devel-bounces@ffmpeg.org] On Behalf

> Of Mark Thompson

> Sent: Thursday, January 24, 2019 07:38

> To: ffmpeg-devel@ffmpeg.org

> Subject: Re: [FFmpeg-devel] [PATCH 2/2] lavc/vaapi_encode: fix the

> mismatched vbvBuf size unit for mpeg2

> 

> On 16/01/2019 14:34, Linjie Fu wrote:

> > hrd_buffer_size and hrd_initial_buffer_fullness are set in bits, while

> > driver takes the vbvBuf size in 16 kbits. The mismatch will cause

> > quality issue.

> >

> > One way to solve this issue in FFmpeg level is set the bufsize

> > specially for mpeg2 as the unit of 16 kbits, and discard the default

> > CBR mode in driver.

> >

> > Fix the quality issue in #7650.

> >

> > Signed-off-by: Linjie Fu <linjie.fu@intel.com>

> > ---

> >  libavcodec/vaapi_encode.c | 8 +++++---

> >  1 file changed, 5 insertions(+), 3 deletions(-)

> 

> The documentation is very clear that these values are all in bits -

> <https://github.com/intel/libva/blob/master/va/va.h#L2095-L2100>.

> 

> Sounds like a driver bug?

> 

> - Mark


Agree it should be fixed in driver level.
And PR has been sent: https://github.com/intel/media-driver/pull/495.

Patch hide | download patch | download mbox

diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
index eda8a36299..c932d9d7fb 100644
--- a/libavcodec/vaapi_encode.c
+++ b/libavcodec/vaapi_encode.c
@@ -1305,9 +1305,11 @@  static av_cold int vaapi_encode_init_rate_control(AVCodecContext *avctx)
     if (avctx->rc_buffer_size)
         hrd_buffer_size = avctx->rc_buffer_size;
     else if (avctx->rc_max_rate > 0)
-        hrd_buffer_size = avctx->rc_max_rate;
+        hrd_buffer_size = ctx->codec->profiles->va_profile > 1 ?
+                        avctx->rc_max_rate : avctx->rc_max_rate >> 14;
     else
-        hrd_buffer_size = avctx->bit_rate;
+        hrd_buffer_size = ctx->codec->profiles->va_profile > 1 ?
+                        avctx->bit_rate : avctx->bit_rate >> 14;
     if (avctx->rc_initial_buffer_occupancy) {
         if (avctx->rc_initial_buffer_occupancy > hrd_buffer_size) {
             av_log(avctx, AV_LOG_ERROR, "Invalid RC buffer settings: "
@@ -1318,7 +1320,7 @@  static av_cold int vaapi_encode_init_rate_control(AVCodecContext *avctx)
         }
         hrd_initial_buffer_fullness = avctx->rc_initial_buffer_occupancy;
     } else {
-        hrd_initial_buffer_fullness = hrd_buffer_size * 3 / 4;
+        hrd_initial_buffer_fullness = FFMAX(avctx->bit_rate, avctx->rc_max_rate) * 3 / 4;
     }
 
     if (avctx->rc_max_rate && avctx->rc_max_rate < avctx->bit_rate) {