intel / intel-vaapi-driver

VA-API user mode driver for Intel GEN Graphics family
https://01.org/linuxmedia
Other
308 stars 127 forks source link

HEVC encode can't handle target_percentage <= 50% in VBR mode #430

Closed uartie closed 5 years ago

uartie commented 5 years ago

FFmpeg sets the target percentage for HEVC VBR encode to 50% by default. However, the driver does not work properly when target percentage <= 50% and causes output stream to have a very low bitrate.

$ ffmpeg -hwaccel vaapi -vaapi_device /dev/dri/renderD128 -v verbose \
  -f rawvideo -pix_fmt yuv420p -s:v 1280x720 -r:v 30 \
  -i ./720p5994_parkrun_ter_1280x720_I420.yuv \
  -vf 'format=nv12,hwupload' -c:v hevc_vaapi -b:v 3500k \
  -vframes 150 -y test.h265

ffmpeg version N-92742-ga07470ba372f Copyright (c) 2000-2018 the FFmpeg developers
  built with gcc 8 (GCC)
  configuration: --prefix=/home/uaeoff/Work/workspace/media/install --disable-static --enable-shared --enable-libdrm --enable-vaapi --enable-libmfx --disable-amf --disable-audiotoolbox --disable-cuda --disable-cuda-sdk --disable-cuvid --disable-d3d11va --disable-dxva2 --disable-libnpp --disable-mmal --disable-nvdec --disable-nvenc --disable-omx --disable-omx-rpi --disable-rkmpp --disable-v4l2-m2m --disable-vdpau --disable-videotoolbox --enable-nonfree --enable-gpl
  libavutil      56. 24.101 / 56. 24.101
  libavcodec     58. 42.104 / 58. 42.104
  libavformat    58. 24.101 / 58. 24.101
  libavdevice    58.  6.101 / 58.  6.101
  libavfilter     7. 46.101 /  7. 46.101
  libswscale      5.  4.100 /  5.  4.100
  libswresample   3.  4.100 /  3.  4.100
  libpostproc    55.  4.100 / 55.  4.100
[AVHWDeviceContext @ 0x117a480] Opened VA display via DRM device /dev/dri/renderD128.
[AVHWDeviceContext @ 0x117a480] libva: VA-API version 1.4.0
[AVHWDeviceContext @ 0x117a480] libva: va_getDriverName() returns 0
[AVHWDeviceContext @ 0x117a480] libva: Trying to open /home/uaeoff/Work/workspace/media/install/lib/dri/i965_drv_video.so
[AVHWDeviceContext @ 0x117a480] libva: Found init function __vaDriverInit_1_4
[AVHWDeviceContext @ 0x117a480] libva: va_openDriver() returns 0
[AVHWDeviceContext @ 0x117a480] Initialised VAAPI connection: version 1.4
[AVHWDeviceContext @ 0x117a480] VAAPI driver: Intel i965 driver for Intel(R) Kaby Lake - 2.4.0.pre1 (2.4.0.pre1).
[AVHWDeviceContext @ 0x117a480] Driver not found in known nonstandard list, using standard behaviour.
[rawvideo @ 0x118b2c0] Estimating duration from bitrate, this may be inaccurate
Input #0, rawvideo, from './720p5994_parkrun_ter_1280x720_I420.yuv':
  Duration: 00:00:20.13, start: 0.000000, bitrate: 331776 kb/s
    Stream #0:0: Video: rawvideo, 1 reference frame (I420 / 0x30323449), yuv420p, 1280x720, 331776 kb/s, 30 tbr, 30 tbn, 30 tbc
Stream mapping:
  Stream #0:0 -> #0:0 (rawvideo (native) -> hevc (hevc_vaapi))
Press [q] to stop, [?] for help
[graph 0 input from stream 0:0 @ 0x119d600] w:1280 h:720 pixfmt:yuv420p tb:1/30 fr:30/1 sar:0/1 sws_param:flags=2
[auto_scaler_0 @ 0x11a0640] w:iw h:ih flags:'bicubic' interl:0
[Parsed_format_0 @ 0x119bdc0] auto-inserting filter 'auto_scaler_0' between the filter 'graph 0 input from stream 0:0' and the filter 'Parsed_format_0'
[auto_scaler_0 @ 0x11a0640] w:1280 h:720 fmt:yuv420p sar:0/1 -> w:1280 h:720 fmt:nv12 sar:0/1 flags:0x4
[hevc_vaapi @ 0x1198d00] Input surface format is nv12.
[hevc_vaapi @ 0x1198d00] Using VAAPI profile VAProfileHEVCMain (17).
[hevc_vaapi @ 0x1198d00] Using VAAPI entrypoint VAEntrypointEncSlice (6).
[hevc_vaapi @ 0x1198d00] Using VAAPI render target format YUV420 (0x1).
[hevc_vaapi @ 0x1198d00] RC mode: VBR, 50% of 7000000 bps over 500 ms.
[hevc_vaapi @ 0x1198d00] RC buffer: 3500000 bits, initial fullness 2625000 bits.
[hevc_vaapi @ 0x1198d00] Using intra, P- and B-frames (supported references: 3 / 1).
[hevc_vaapi @ 0x1198d00] All wanted packed headers available (wanted 0xd, found 0x1f).
[hevc_vaapi @ 0x1198d00] Using level 3.1.
Output #0, hevc, to 'test.h265':
  Metadata:
    encoder         : Lavf58.24.101
    Stream #0:0: Video: hevc (hevc_vaapi) (Main), 1 reference frame, vaapi_vld, 1280x720, q=-1--1, 3500 kb/s, 30 fps, 30 tbn, 30 tbc
    Metadata:
      encoder         : Lavc58.42.104 hevc_vaapi
No more output streams to write to, finishing.e=00:00:04.46 bitrate= 469.5kbits/s speed=4.41x    
frame=  150 fps=133 q=-0.0 Lsize=     324kB time=00:00:04.96 bitrate= 534.3kbits/s speed=4.42x    
video:324kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.000000%
Input file #0 (./720p5994_parkrun_ter_1280x720_I420.yuv):
  Input stream #0:0 (video): 150 packets read (207360000 bytes); 150 frames decoded; 
  Total: 150 packets (207360000 bytes) demuxed
Output file #0 (test.h265):
  Output stream #0:0 (video): 150 frames encoded; 150 packets muxed (331699 bytes); 
  Total: 150 packets (331699 bytes) muxed
[AVIOContext @ 0x1199680] Statistics: 0 seeks, 2 writeouts
[AVIOContext @ 0x11946c0] Statistics: 207360000 bytes read, 0 seeks

If user sets -maxrate to a value > 50% of target bitrate on ffmpeg command line, then the bitrate result looks normal.

See https://trac.ffmpeg.org/ticket/7629 for more details and root-cause analysis.

xhaihao commented 5 years ago

@uartie could you give a try with https://github.com/xhaihao/intel-vaapi-driver/commit/6b2825e99715126e3d8ec277a434caa580d1e30f ?

uartie commented 5 years ago

@xhaihao Yes xhaihao@6b2825e patch fixes this for me. Also, I verified this patch has no smoke test regressions with CQP and CBR cases in ffmpeg-vaapi and CQP, CBR and VBR cases in gst-vaapi. LGTM

uartie commented 5 years ago

@xhaihao will you be submitting this patch?

uartie commented 5 years ago

@xhaihao ping

xhaihao commented 5 years ago

@uartie Sorry for my slow response and thanks for your testing. I will submit the patch ASAP.