【工程师分享】使用ffmpeg把mp4转换为NV12文件

作者:付汉杰,hankf@xilinx.com,文章转载自:博客园

在测试MPSoC VCU的编解码时,经常需要使用NV12 YUV文件。YUV文件很大,所以经常依靠解压MP4等文件来产生NV12 YUV文件。 FFMpeg是一个强大的工具,可以用来从MP4文件生成NV12 YUV文件。

但是在使用FFMpeg时,发现使用选项“-pixel_format nv12”时,得到的文件实际上是yuv420p格式的,不是NV12格式。需要使用选项“-pix_fmt nv12”,才能得到NV12格式的文件。如果格式不对,播放出来的图像是不正确的。

产生正确的NV12格式的文件的记录:

Microsoft Windows [Version 10.0.17134.2026]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\Temp\video>ffmpeg -i xilinx_1080p_h264.mp4 -vcodec rawvideo -s 1920x1080 -pix_fmt nv12  -vframes 300 xilinx_1080p_nv12.yuv
ffmpeg version N-89369-g5a93a85fd0 Copyright (c) 2000-2017 the FFmpeg developers
  built with gcc 7.2.0 (GCC)
  configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-bzlib --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvorbis --enable-cuda --enable-cuvid --enable-d3d11va --enable-nvenc --enable-dxva2 --enable-avisynth --enable-libmfx
  libavutil      56.  4.100 / 56.  4.100
  libavcodec     58.  6.102 / 58.  6.102
  libavformat    58.  2.103 / 58.  2.103
  libavdevice    58.  0.100 / 58.  0.100
  libavfilter     7.  6.100 /  7.  6.100
  libswscale      5.  0.101 /  5.  0.101
  libswresample   3.  0.101 /  3.  0.101
  libpostproc    55.  0.100 / 55.  0.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'xilinx_1080p_h264.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf56.40.101
  Duration: 00:02:22.58, start: 0.000000, bitrate: 4313 kb/s
    Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], 4175 kb/s, 50 fps, 50 tbr, 12800 tbn, 100 tbc (default)
    Metadata:
      handler_name    : VideoHandler
    Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 128 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> rawvideo (native))
Press [q] to stop, [?] for help
Output #0, rawvideo, to 'xilinx_1080p_nv12.yuv':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf58.2.103
    Stream #0:0(eng): Video: rawvideo (NV12 / 0x3231564E), nv12, 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 1244160 kb/s, 50 fps, 50 tbn, 50 tbc (default)
    Metadata:
      handler_name    : VideoHandler
      encoder         : Lavc58.6.102 rawvideo
frame=  300 fps=234 q=-0.0 Lsize=  911250kB time=00:00:06.00 bitrate=1244160.0kbits/s speed=4.67x
video:911250kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.000000%

上面ffmpeg的输出含有“rawvideo (NV12 / 0x3231564E), nv12”,说明它使用了NV12格式。

产生YUV420P格式的文件的记录:

Microsoft Windows [Version 10.0.17134.2087]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\Temp\video>ffmpeg -y -i xilinx_1080p_h264.mp4 -vcodec rawvideo -s 1920x1080 -pixel_format nv12 -vframes 300 xilinx_1080p_nv12.yuv
ffmpeg version N-89369-g5a93a85fd0 Copyright (c) 2000-2017 the FFmpeg developers
  built with gcc 7.2.0 (GCC)
  configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-bzlib --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvorbis --enable-cuda --enable-cuvid --enable-d3d11va --enable-nvenc --enable-dxva2 --enable-avisynth --enable-libmfx
  libavutil      56.  4.100 / 56.  4.100
  libavcodec     58.  6.102 / 58.  6.102
  libavformat    58.  2.103 / 58.  2.103
  libavdevice    58.  0.100 / 58.  0.100
  libavfilter     7.  6.100 /  7.  6.100
  libswscale      5.  0.101 /  5.  0.101
  libswresample   3.  0.101 /  3.  0.101
  libpostproc    55.  0.100 / 55.  0.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'xilinx_1080p_h264.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf56.40.101
  Duration: 00:02:22.58, start: 0.000000, bitrate: 4313 kb/s
    Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], 4175 kb/s, 50 fps, 50 tbr, 12800 tbn, 100 tbc (default)
    Metadata:
      handler_name    : VideoHandler
    Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 128 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> rawvideo (native))
Press [q] to stop, [?] for help
Output #0, rawvideo, to 'xilinx_1080p_raw_nv12.yuv':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf58.2.103
    Stream #0:0(eng): Video: rawvideo (I420 / 0x30323449), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 1244160 kb/s, 50 fps, 50 tbn, 50 tbc (default)
    Metadata:
      handler_name    : VideoHandler
      encoder         : Lavc58.6.102 rawvideo
frame=  300 fps=241 q=-0.0 Lsize=  911250kB time=00:00:06.00 bitrate=1244160.0kbits/s speed=4.81x
video:911250kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.000000%

上面ffmpeg的输出含有“rawvideo (I420 / 0x30323449), yuv420p”,说明它使用了yuv420p格式。

使用ffplay播放NV12 YUV文件的记录如下:

C:\Temp\video>ffplay -f rawvideo -video_size 1920x1080 -pix_fmt nv12 xilinx_1080p_nv12.yuv
ffplay version N-89369-g5a93a85fd0 Copyright (c) 2003-2017 the FFmpeg developers
  built with gcc 7.2.0 (GCC)
  configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-bzlib --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvorbis --enable-cuda --enable-cuvid --enable-d3d11va --enable-nvenc --enable-dxva2 --enable-avisynth --enable-libmfx
  libavutil      56.  4.100 / 56.  4.100
  libavcodec     58.  6.102 / 58.  6.102
  libavformat    58.  2.103 / 58.  2.103
  libavdevice    58.  0.100 / 58.  0.100
  libavfilter     7.  6.100 /  7.  6.100
  libswscale      5.  0.101 /  5.  0.101
  libswresample   3.  0.101 /  3.  0.101
  libpostproc    55.  0.100 / 55.  0.100
Option -pix_fmt is deprecated, use -pixel_format.
[rawvideo @ 000001fca7cf5a80] Estimating duration from bitrate, this may be inaccurate
Input #0, rawvideo, from 'xilinx_1080p_nv12.yuv':
  Duration: 00:00:12.00, start: 0.000000, bitrate: 622080 kb/s
    Stream #0:0: Video: rawvideo (NV12 / 0x3231564E), nv12, 1920x1080, 622080 kb/s, 25 tbr, 25 tbn, 25 tbc
   2.91 M-V: -0.037 fd=   3 aq=    0KB vq=18225KB sq=    0B f=0/0

FFMpeg关于rawvideo的说明。

rawvideo demuxer AVOptions:
  -video_size        <image_size> .D...... set frame size
  -pixel_format     <string>     .D...... set pixel format (default "yuv420p")
  -framerate         <video_rate> .D...... set frame rate (default "25")

最新文章

最新文章