FFmpeg 软编码h.264与H.265(从简到深)

当前网络中常见的视频编码格式要数H.264最为火热,支持H.264的封装格式有很多,如FLV ,MP4 , HLS(M3U8),MKV ,TS等格式;

FFMpeg本身并不支持H.264的编码器,而是由FFMpeg的第三方模块对其进行支持,例如x264和OpenH264,二者各有各的优势。由于OpenH264开源比较晚,所以x264还是当前最常用的编码器,这里将重点介绍FFMpeg中x264的使用;使用x264进行h.264编码时,所支持的像素格式主要包括yuy420p,yuvj420p,yuv422p, yuvj422p, yuv444p ,yuvj444p ,nv12 ,nv16, nv21,.

通过以下命令可以查看支持的像素格式:

[root@localhost ~]# ffmpeg -h encoder=libx264
 
Encoder libx264 [libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10]:
    General capabilities: delay threads 
    Threading capabilities: other
    Supported pixel formats: yuv420p yuvj420p yuv422p yuvj422p yuv444p yuvj444p nv12 nv16 nv21 yuv420p10le yuv422p10le yuv444p10le nv20le gray gray10le

因为其所支持的像素彩格式比较多,使用x264支持的范围更广。下面就来详细介绍FFmpeg中x264的参数

1.1 x264编码参数简介

x264参数在FFmpeg中可以使用很多参数,同样也可以使用x264本身的参数来控制,具体参数列表见表:1-1

1-1 x264参数

 

以上为h.264编码时用到的常见的参数,设置参数后编码生成的文件可以通过一些外部协助工具进行查看例如:ELecard, Bitrate , Viewer , ffprobe等。

1.2 H.264编码举例

1.1中已经给出了FFmpeg中H264(ISO14496b标准中的AVC)编码器的操作参数,下面就来列举一些实际中常用的例子。

1. 编码器预设设置preset

从FFmpeg的x264参考说明中可以看到,可以使用x264-full help 查看preset设置的详细说明,找到x264帮助信息中的preset参数项之后,可以看到其包含了以下几种预设参数,预设参数的详细设置具体如下。

·ultrafast: 最快的编码方式

除了默认设置之外,还增加了如下参数设置:

--no-8x8dct --aq-mode 0 --b-adapt 0 --bframes 0 --no-cabac --no-deblock --no-mbtree --me dia --no-mixed-refs --partitions none --rc-lookahead 0 -ref 1 --scenecut 0 --subme 0 --noweightb --weightp 0 

`superfast: 超级快速的编码方式

  除了默认设置之外,还增加了如下参数设置:

--no-mbtree --me dia --no-mixed-refs --partitiuons i8x8,i4x4 --rc-lookahead 0 --ref 1 -subme 1 --trellis 0 --weightp 1 

`veryfast: 非常快速的编码方式

   除了默认设置之外,还增加了如下参数设置:

--no-mixed-refs --rc-lookanhead 10 -ref 1 -subme 2 --trellis 0 -wgightp 1

`faster: 稍微快速的编码方式

    除了默认设置之外,还增加了如下参数设置:

--no-mixed-refs -rc-lookahead 20 -ref 2 --subme 4 --weightp 1

`fast: 快速的编码方式

    除了默认设置之外,还增加了如下参数设置:

--rc-lookahead 30 -ref 2 --subme 6 --weightp 1

` medium: 折中的编码方式

    参数全部为默认设置

·slow: 慢的编码方式

    除了默认设置之外,还增加了如下参数设置:

--b-adapt 2 --direct auto --me umh --rc-lookahead 50 --ref 5 --subme 8

 `slower: 更慢的编码方式

   除了默认设置之外,还增加了如下参数设置:

--b-adapt 2 --direct auto --me -umh --partitions all --rc-lookahead 60 --ref 8 --subme 9 --trellis 2

`veryslow: 非常慢的编码方式

      除了默认设置之外,还增加了如下参数设置:

--b-adapt 2 --bframes 8 --direct auto --me umh --merange 24 -partitions all -ref 16 -subme 10 --trellis 2 --rc-lookahead 60 

placebo: 最慢的编码方式

     除了默认设置之外,还增加了如下参数设置:

--bframes 16 --b-adapt 2 --direct auto --slow-firstpass --no-fast-pskip --me tesa --merange 24 --partitions all --rc-lookahead 60 --ref 16 --subme 11 --trellis 2

  随着所设置参数的不同,所编码出来的清晰度也会有所不同,设置相关的预设参数之后,有很多参数也会被设置所影响,因此需要了解相关的参数含义。为了方便操作,通过prese进行设置即可,下面就来看一下相同的机器中,设置ultrafast与设置medium预设参数之后转码效率的对比:

[root@localhost ffmpeg]# ffmpeg -i 1080_test.mp4 -vcodec libx264 -preset ultrafast -b:v 2000k output.mp4
ffmpeg version 4.4-static https://johnvansickle.com/ffmpeg/  Copyright (c) 2000-2021 the FFmpeg developers
  built with gcc 8 (Debian 8.3.0-6)
  configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --disable-ffplay --disable-indev=sndio --disable-outdev=sndio --cc=gcc --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gmp --enable-libgme --enable-gray --enable-libaom --enable-libfribidi --enable-libass --enable-libvmaf --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librubberband --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libvorbis --enable-libopus --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libdav1d --enable-libxvid --enable-libzvbi --enable-libzimg
  libavutil      56. 70.100 / 56. 70.100
  libavcodec     58.134.100 / 58.134.100
  libavformat    58. 76.100 / 58. 76.100
  libavdevice    58. 13.100 / 58. 13.100
  libavfilter     7.110.100 /  7.110.100
  libswscale      5.  9.100 /  5.  9.100
  libswresample   3.  9.100 /  3.  9.100
  libpostproc    55.  9.100 / 55.  9.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '1080_test.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf58.76.100
  Duration: 00:00:41.67, start: 0.000000, bitrate: 2296 kb/s
  Stream #0:0(und): Video: h264 (High 4:2:2) (avc1 / 0x31637661), yuv422p, 1920x1080 [SAR 1:1 DAR 16:9], 2294 kb/s, 24 fps, 24 tbr, 12288 tbn, 48 tbc (default)
    Metadata:
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
Press [q] to stop, [?] for help
[libx264 @ 0x74e9780] using SAR=1/1
[libx264 @ 0x74e9780] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2 AVX512
[libx264 @ 0x74e9780] profile High 4:2:2, level 4.0, 4:2:2, 8-bit
[libx264 @ 0x74e9780] 264 - core 161 r3048 b86ae3c - H.264/MPEG-4 AVC codec - Copyleft 2003-2021 - http://www.videolan.org/x264.html - options: cabac=0 ref=1 deblock=0:0:0 analyse=0:0 me=dia subme=0 psy=1 psy_rd=1.00:0.00 mixed_ref=0 me_range=16 chroma_me=1 trellis=0 8x8dct=0 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=0 threads=34 lookahead_threads=5 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=0 weightp=0 keyint=250 keyint_min=24 scenecut=0 intra_refresh=0 rc=abr mbtree=0 bitrate=2000 ratetol=1.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=0
Output #0, mp4, to 'output.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf58.76.100
  Stream #0:0(und): Video: h264 (avc1 / 0x31637661), yuv422p(progressive), 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 2000 kb/s, 24 fps, 12288 tbn (default)
    Metadata:
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]
      encoder         : Lavc58.134.100 libx264
    Side data:
      cpb: bitrate max/min/avg: 0/0/2000000 buffer size: 0 vbv_delay: N/A
frame= 1000 fps=386 q=-1.0 Lsize=   26827kB time=00:00:41.62 bitrate=5279.6kbits/s speed=16.1x    
video:26822kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.018856%
[libx264 @ 0x74e9780] frame I:4     Avg QP:21.00  size:243519
[libx264 @ 0x74e9780] frame P:996   Avg QP:25.44  size: 26597
[libx264 @ 0x74e9780] mb I  I16..4: 100.0%  0.0%  0.0%
[libx264 @ 0x74e9780] mb P  I16..4:  5.5%  0.0%  0.0%  P16..4: 15.9%  0.0%  0.0%  0.0%  0.0%    skip:78.5%
[libx264 @ 0x74e9780] final ratefactor: 30.80
[libx264 @ 0x74e9780] coded y,uvDC,uvAC intra: 22.2% 39.8% 9.3% inter: 6.4% 5.5% 2.1%
[libx264 @ 0x74e9780] i16 v,h,dc,p: 39% 24% 16% 21%
[libx264 @ 0x74e9780] i8c dc,h,v,p: 38% 19% 30% 13%
[libx264 @ 0x74e9780] kb/s:5273.23

从命令行执行后的输出内容中可以看到,转码的预设参数为ultrafas模式,转码的速度为16.1倍数,接下来再看一下设置为medium模式后的速度“

[root@localhost ffmpeg]# ffmpeg -i 1080_test.mp4 -vcodec libx264 -preset medium -b:v 2000k output2.mp4 
ffmpeg version 4.4-static https://johnvansickle.com/ffmpeg/  Copyright (c) 2000-2021 the FFmpeg developers
  built with gcc 8 (Debian 8.3.0-6)
  configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --disable-ffplay --disable-indev=sndio --disable-outdev=sndio --cc=gcc --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gmp --enable-libgme --enable-gray --enable-libaom --enable-libfribidi --enable-libass --enable-libvmaf --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librubberband --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libvorbis --enable-libopus --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libdav1d --enable-libxvid --enable-libzvbi --enable-libzimg
  libavutil      56. 70.100 / 56. 70.100
  libavcodec     58.134.100 / 58.134.100
  libavformat    58. 76.100 / 58. 76.100
  libavdevice    58. 13.100 / 58. 13.100
  libavfilter     7.110.100 /  7.110.100
  libswscale      5.  9.100 /  5.  9.100
  libswresample   3.  9.100 /  3.  9.100
  libpostproc    55.  9.100 / 55.  9.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '1080_test.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf58.76.100
  Duration: 00:00:41.67, start: 0.000000, bitrate: 2296 kb/s
  Stream #0:0(und): Video: h264 (High 4:2:2) (avc1 / 0x31637661), yuv422p, 1920x1080 [SAR 1:1 DAR 16:9], 2294 kb/s, 24 fps, 24 tbr, 12288 tbn, 48 tbc (default)
    Metadata:
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
Press [q] to stop, [?] for help
[libx264 @ 0x5d4f780] using SAR=1/1
[libx264 @ 0x5d4f780] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2 AVX512
[libx264 @ 0x5d4f780] profile High 4:2:2, level 4.0, 4:2:2, 8-bit
[libx264 @ 0x5d4f780] 264 - core 161 r3048 b86ae3c - H.264/MPEG-4 AVC codec - Copyleft 2003-2021 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=34 lookahead_threads=5 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=24 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=abr mbtree=1 bitrate=2000 ratetol=1.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
Output #0, mp4, to 'output2.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf58.76.100
  Stream #0:0(und): Video: h264 (avc1 / 0x31637661), yuv422p(progressive), 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 2000 kb/s, 24 fps, 12288 tbn (default)
    Metadata:
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]
      encoder         : Lavc58.134.100 libx264
    Side data:
      cpb: bitrate max/min/avg: 0/0/2000000 buffer size: 0 vbv_delay: N/A
frame= 1000 fps=106 q=-1.0 Lsize=   22165kB time=00:00:41.54 bitrate=4370.9kbits/s speed=4.42x    
video:22152kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.057650%
[libx264 @ 0x5d4f780] frame I:11    Avg QP:14.58  size: 98096
[libx264 @ 0x5d4f780] frame P:295   Avg QP:19.14  size: 33121
[libx264 @ 0x5d4f780] frame B:694   Avg QP:20.69  size: 17050
[libx264 @ 0x5d4f780] consecutive B-frames:  2.3% 14.8%  2.1% 80.8%
[libx264 @ 0x5d4f780] mb I  I16..4: 41.7% 47.5% 10.7%
[libx264 @ 0x5d4f780] mb P  I16..4:  3.3%  8.8%  1.1%  P16..4: 23.3%  4.2%  1.8%  0.0%  0.0%    skip:57.4%
[libx264 @ 0x5d4f780] mb B  I16..4:  0.7%  1.8%  0.4%  B16..8: 15.5%  1.4%  0.3%  direct: 1.5%  skip:78.5%  L0:40.5% L1:54.9% BI: 4.5%
[libx264 @ 0x5d4f780] final ratefactor: 23.41
[libx264 @ 0x5d4f780] 8x8 transform intra:62.4% inter:72.6%
[libx264 @ 0x5d4f780] coded y,uvDC,uvAC intra: 45.1% 68.5% 22.5% inter: 5.7% 7.3% 2.2%
[libx264 @ 0x5d4f780] i16 v,h,dc,p: 44% 20%  9% 27%
[libx264 @ 0x5d4f780] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 32% 15% 18%  5%  6%  7%  5%  7%  5%
[libx264 @ 0x5d4f780] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 30% 22%  9%  5%  9%  8%  7%  6%  4%
[libx264 @ 0x5d4f780] i8c dc,h,v,p: 43% 17% 31%  8%
[libx264 @ 0x5d4f780] Weighted P-Frames: Y:0.7% UV:0.0%
[libx264 @ 0x5d4f780] ref P L0: 61.7% 16.4% 16.4%  5.5%
[libx264 @ 0x5d4f780] ref B L0: 87.4% 10.5%  2.1%
[libx264 @ 0x5d4f780] ref B L1: 96.7%  3.3%
[libx264 @ 0x5d4f780] kb/s:4355.11

从以上输出内容可以看到,设备medium模式后,转码速度为0.833倍速,速度虽然降低了。但画质却有了明显的提升,对比效果图如下:

 

ultrafast与medium标准输出视频清晰度对比

很显然,对比图中的上图是通过预设参数ultrafas转码之后的效果,下边的图像是通过medium转码之后的效果上下图像相差比较大,上边图像的马赛克多一些,图中草的对比比较明显,主要是因为两个preset中所设置的参数略有不同,详细可以参考前边的参数说明。

本文福利,免费领取C++音视频学习资料包、技术视频,内容包括(音视频开发,面试题,FFmpeg webRTC rtmp hls rtsp ffplay srs↓↓↓↓↓↓见下面↓↓文章底部↓↓

 

2. H264编码优化参数 tune

使用tune参数调优h.264编码时,可以包含如下几个场景:film , animation , grain , stilimage , psnr , ssim ,fastdecode , zerolatency ; 这几种场景所使用的x264参数也各有不同,具体如下。

·film

除去默认参数之外,还需要设置如下参数:

--deblock -1:-1 --psy-rd <unset>:0.15

`animation 

   除去默认参数之外,还需要设置如下参数:

--bframes {+2} --deblock 1:1 --psy-rd 0.4:<unset> --aq-strength 0.6 --ref {Double if >1 else 1}

 `grain

   除去默认参数之外,还需要设置如下参数:

--aq-strength 0.5 --no-dct-decimate --deadzone-inter 6 --deadzone-intra 6 --delock -2:-2 --ipration 1.1 --pbratio 1.1 --psy-rd <unset>:0.25 --qcomp 0.8 

`stillimage

   除去默认参数之外,还需要设置如下参数:

--aq-strebgth 1.2 --deblock -3:-3 --psy-rd 2.0:0.7

`psnr

   除去默认参数之外,还需要设置如下参数:

--aq-mode 0 --no-psy

`ssim

   除去默认参数之外,还需要设置如下参数:

--aq-mode 2 --no-psy

`fastdecode

   除去默认参数之外,还需要设置如下参数:

--no-cabac --no-debblock --no-weightb --weightp 0

`zerolatency 

   除去默认参数之外,还需要设置如下参数:

--bframes 0 --force-cfr --no-mbtree --sync-lookahead 0 --sliced-threads --rc-lookahead 0

在使用ffmpeg与x264进行H.264直播编码并进行推流时,只用tune参数的zerolatency将会提升效率,因为其降低了因编码导致的延迟。

3.H.264的profile与level设置

这里的profile(档次)与level(等级)的设置与H.265标准文档ISO-14496-part10中描述的profile,level的信息基本相同,x264编码器支持Baseline,Extented, Mian ,High,High10,Hitgh422,Hig444等7种profile参数设置,根据profile的不同,编码出来的视频的很多参数也有所不同,具体情况可以参考表。

x264编码profile参数表

 

   level设置则与标准的ISO-14496-Part10参考中的Annex A中描述的表格完全相同,见下表

H.264level参数

 

下面使用baseline profile编码一个H.264视频,然后使用high profile编码一个h.264视频,分析两类不同profile编码出来的视频的区别,从表中所示的profile参数中可以看到,使用baseline编码出来的H.264视频不会包含B Slice,而使用main profile, high profile编码出来的视频,均可以包含B Slice, 下面就来着重查看baseline与high两种不同profile编码出来的视频是否包含B slice

首先使用FFmpeg编码生成baseline与high两种profile的视频:

ffmpeg -i input.mp4 -vcodec libx264 -profile:v baseline -level 3.1 -s 352x288 -an -y -t 10 ouput_baseline.ts
ffmpeg -i input.mp4 -vcodec libx264 -prifile:v higs -level 3.1 -s 352x288 -an -y -t 10 output_higs.ts

 从以上的输出结果可以看到共执行了两次ffmpeg,分别生成output_baseline.ts与output_high.ts两个文件。下面使用ffprobe查看这两个文件包含B帧的情况:

ffprobe -v quiet -show_frames -select_streams v output_baseline.ts | grep "pict_type=B" | wc -l
0
ffprobe -v quit -show_frames -select_streams v output_high.ts | grep "pict_type=B"| wc -l 
140

从输出结果中可以看到,baseline profile中包含了0个B帧,而high profile 的视频中包含了140个B帧。当进行实时流媒体直播,采用baseline编码相对main或high的profile会更可靠一些;但适当地加入B帧能够有效地降低码率,所以应根据需要与具体的业务场景进行选择。

4. 控制场景切换关键帧插入参数sc_threshold

在FFmpeg,通过命令行的-g参数设置以帧数间隔为GOP的长度,但是当遇到场景切换时,例如从一个画面突然变成另外一个画面是,会强行插入一个关键帧,这时GOP的间隔将会重新开始,这样的场景切换在点播视频文件中会频频遇到,如果将点播文件进行M3U8切片,或者将点博文件进行串流虚拟直播时,GOP的间隔也会出现相同的情况,为了避免这种情况的产生,可以通过使用sc_threshold参数进行设定以决定是否在场景切换时插入关键帧。

下面执行ffmpeg命令控制编码的GOP大小,生成MP4后使用Elecard StreamEye观察GOP的情况:

ffmpeg -i input.mp4 -c:v libx264 -g 50 -t 60 output.mp4

根据这条命令可以看出,每帧被设置一个GOP间隔,生成60秒的MP4视频,接下来查看一下GOP的情况,通如下图所示:

 

图-查看不规则的GOP视频

   从图中可以看出,其中有一段GOP的间距比较短,这是强行插入GOP而导致的,这个情形插入的GOP是由于场景切换导致的GOP插入。为了使得GOP的插入更加均匀,使用参数sc_threshold即可,下面来看一下效果:

ffmpeg -i input.mp4 -c:v libx264 -g 50 -sc_threshold 0 -t 60 -y output.mp4

  执行完这条命令之后,GOp间隔被设置为50帧,并且场景切换时不插入关键帧,执行完之后生成的MP4效果如图所示,GOP非常均匀,均为50帧一个GOP,场景切换时并没有强行插入GOP,这样做有一个好处,那就是可以控制关键帧,在进行视频切换时将会更加方便,如下图所示:

 

图-查看固定GOP长度视频

5.设置x264内部参数x264opts

由于FFmpeg设置x264参数时增加的参数比价多,使用ffmpeg开放了x264opts,可以通过这个参数设置x264内部私有参数。下面举个例子,控制I帧 P帧,B帧的顺序及出现频率,首先分析一下设置的GOP参数,如果视频GOP设置为50帧,那么如果在这50帧中不希望出现B帧,则客户只需要将x264参数bframes设置为0即可:

ffmpeg -i input.mp4 -c:v libx264 -x264opts "bframes=0" -g 50 -sc_threshold 0 output.mp4

命令执行完毕后,使用Elecard StreamEye 查看帧的信息,结果如下图:

 

图-Elecard查看无B帧视频

从图中可以看出,output.mp4中H.264的帧排列中并不包含B帧,全部为P帧与I帧。

如果希望控制I帧,P帧,B帧的频率与规律,可以通过控制GOP中B帧数来实现,P帧的频率可以通过x264的参数b-adapt进行设置。

例如设置GOP中,每2P帧之间存放3个B帧:

ffmpeg -i input.mp4 -c:v libx264 -x264opts "bframes3:b-adapt=0" -g 50 -sc_threshold 0 output.mp4

命令执行完之后,使用Elcard StreamEye查看帧信息,如下图所示。

 

 图-Elecard查看固定帧排列视频

  视频中的B帧越多,同等码率是清晰度将会越高,但是B帧越多,编码和解码所带来的复杂度也就越高,所以合理地使用B帧非常重要,尤其是在进行清晰度与码率衡量时。

6.CBR恒定码率设置参数

从前面对x264参数的介绍中可以看出,编码能赊账VBR,CBR的编码模式,VBR为可以变码率,CBR为恒定码率。尽管现在互联网上所看到的视频中VBR居多,但CBR依然存在;说明就来介绍一下CBR码率视频的制作。ffmpeg是通过参数-b:v来指定视频的编码码率的,当时设定的码率是平均码率,并不能够很好地控制最大码率及最小码率的波动,如果需要控制最大码率和最小码率以控制码率的波动,则需要使用FFmpeg的三个参数-b:v,maxrate,minrate。同时为了更好地控制编码时的波动,还可以设置编码时buffer的大小,buffer的大小使用参数-bufsize设置即可,buffer的设置不是越小越好,而是要设置的恰到好处,例如下面例子中设置1Mbit/s码率的视频,bufsize设置为50kb,可以很好地控制码率被动:

ffmpeg -i input.mp4 -c:v libx264 -x264opts "bframes=10:b-adapt=0" -b:v 1000k -maxrate 1000k -minrate 1000k -bufsize 50k -nal-hrd -cbr -g 50 -sc_threshold 0 output.ts

下面就来分析一下这条命令,具体如下。

设置B帧的个数,并且是每两个P帧之间包含10个B帧

设置视频码率为1000kbit/s

设置最大码率为1000kbit/s

设置最小码率为1000kbit/s

设置编码的buffer大小为50kb

设置h264的编码HRD信号形式为CBR

设置每个50帧一个GOP

设置场景切换不强行插入关键帧

根据上述参数设置之后生成的output.ts文件,使用bireate Viewer观察其码率波动效果,结果如下图所示:

 图 使用Bitrate Viewer查看CBR编码视频信息

   从图中可以看到码率波动为最小996kbit/s,最大码率为1001kbit/s,码率得到了控制

   接下来使用Elecard StreamEye查看一下视频流信息,如下图所示。

 图 Elecard 查看CBR视频信息

   可以看到流的码率类型(bitrate type)为CBR,至此CBR设置完毕。

说明:
  在FFmpeg中进行H.265编码时,可以采用x265进行编码,H.264参数与x264的编码参数相差不多,基本可以通用。

原文链接:FFmpeg 软编码h.264与H.265(从简到深) - 视频 - 我爱音视频网 - 构建全国最权威的音视频技术交流分享论坛

本文福利,免费领取C++音视频学习资料包、技术视频,内容包括(音视频开发,面试题,FFmpeg webRTC rtmp hls rtsp ffplay srs↓↓↓↓↓↓见下面↓↓文章底部↓↓ 

猜你喜欢

转载自blog.csdn.net/m0_60259116/article/details/125679744