1. ffmpeg 命令
1.1
-c:v
设置编码器
-y
覆盖输出文件
-vf scale=${w}x${h}
设置放缩参数
ffmpeg 硬件编码命令:
${ffmpeg_exe} -hwaccel cuda -hwaccel_output_format cuda -i /root/test_packet/test_1500k_1920_1080.mp4 -c:v h264_nvenc -preset slow ./abc.mp4
HDR 编码
ffmpeg -y -nostdin -hide_banner -v info -analyzeduration 400000000 -i 6v0hphj1odgb6lla2om1582531261727_10bit.mp4 -an -max_interleave_delta 0 -flags +global_header -max_muxing_queue_size 3000 -map 0:v:0 -c:v libx264 -qp 28 -vsync 0 -x264opts no-scenecut=1:stitchable=1 -map_metadata -1 6v0hphj1odgb6lla2om1582531261727_10bit_loss.mp4
FFMPEG 使用 hwupload_cuda
ffmpeg -loglevel debug -threads 4 -hwaccel cuvid -c:v mpeg2_cuvid -i "e:input.ts" -filter:v hwupload_cuda,scale_npp=w=1920:h=1080:interp_algo=lanczos -c:v h264_nvenc -b:v 4M -maxrate:v 5M -bufsize:v 8M -profile:v main -level:v 4.1 -rc:v vbr_hq -rc-lookahead:v 32 -spatial_aq:v 1 -aq-strength:v 15 -coder:v cabac -f mp4 "e:output.mp4"
1.2. ffmpeg 如何添加一个filter
https://blog.csdn.net/qq_36783046/article/details/86405469
1.3,
-hwaccel cuvid:指定使用cuvid硬件加速
-c:v h264_cuvid:使用h264_cuvid进行视频解码
-c:v h264_nvenc:使用h264_nvenc进行视频编码
-vf scale_npp=1280:-1:指定输出视频的宽高,注意,这里和软解码时使用的-vf scale=x:x不一样
2. av_frame_ref av_frame_unref
av_frame_ref拷贝所有的字段,包括extern_data这个二维数组也进行了拷贝,所以说真实的图像数据还是没有拷贝的。
av_frame_unref 也就是把上面那个函数分配出来的字段全部重置,分配的全部free, 但是音视频数据他是不会free的
3. ffmpeg framesync
https://www.cnblogs.com/TaigaCon/p/10193627.html
4. ffmpeg 两路输入, 同步问题
4.1 报错: Error while filtering: Invalid argument
查找原因:
在 ffmpeg-4.1/libavutil/imgutils.c :99 打断点, 程序运行在了断点
if (!desc || desc->flags & AV_PIX_FMT_FLAG_HWACCEL) return AVERROR(EINVAL);
结论:ff_framesync_dualinput_get 不支持cuda 帧
解决办法: 肯定有解决办法 我们不知道
5. ffmpeg 编译
https://trac.ffmpeg.org/wiki/CompilationGuide
6. ffmpeg 增加filter
vi configure
--enable-libvmaf_cuda enable vmaf_cuda filter via libvmaf_cuda [no] libvmaf_cuda libvmaf_cuda_filter_deps="libvmaf_cuda pthreads" enabled libvmaf_cuda && require_pkg_config libvmaf_cuda "libvmaf_cuda >= 0.5.0" libvmaf_cuda.h compute_vmaf_cuda && cuda_sdk
cd libavfiltre
vi Makefile
vi allfilter.c
7, ffmpeg 获取硬件解码的像素格式
AVHWFramesContext *frames_ctx = (AVHWFramesContext*)inlink->hw_frames_ctx->data; AVCUDADeviceContext *hwctx = (AVCUDADeviceContext *)frames_ctx->device_ctx->hwctx; const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get( frames_ctx->sw_format );
8 讲ffmpeg 的帧保存为文件
static int save_av_frame( AVFrame * frame, const char* name ) { FILE * file = fopen(name,"wb"); uint8_t* dataptr = NULL; int h[3] = {frame->height, frame->height/2, frame->height/2}; int w[3] = {frame->width, frame->width/2 , frame->width/2}; int bpe = frame->linesize[0] / frame->width; int wfail = 0; for(int k=0;k!=3;++k){ dataptr = frame->data[k]; size_t linesize = frame->linesize[k]; size_t len = w[k] * bpe; for(int j=0;j!=h[k]; ++ j){ size_t wlen = fwrite(dataptr,1, len, file ); dataptr += linesize; if(wlen != len){ wfail = 1; printf("write fail "); break; } } if(wfail) break; } fclose(file); return 0; }
9. ffmpeg 计算vmaf
$ffmpeg -v info -analyzeduration 400000000 -i ${main} -an -i ${ref} -an -lavfi libvmaf=" model_path=/data/luoyinjie/vmaf_model/vmaf_4k_v0.6.1.pkl:psnr=0:log_fmt=json" -f null /dev/null
10 x264预设类参数详解
https://blog.csdn.net/cabbage2008/article/details/50275771
11 ffmpeg 转换像素格式
struct SwsContext *m_pSwsContext; m_pSwsContext = sws_getContext(src->width, src->height, (enum AVPixelFormat) src->format, dscW, dscH, (AVPixelFormat)dscFormat, SWS_BILINEAR, NULL, NULL, NULL); ret = sws_scale(m_pSwsContext, src->data, src->linesize, 0, src->height, dst->data, dst->linesize); sws_freeContext(m_pSwsContext);
12 将HDR视频改为SDR
$exec -i $src -c:v libx264 -c:a copy -max_muxing_queue_size 9999 -vf zscale=transfer=bt709:matrix=bt709:pin=bt709 $dst
使用ffmpeg直接压制HDR x265(HEVC)视频(保留HDR元数据)转码命令
ffmpeg -loglevel panic -i "输入文件名.mkv" -strict -1 -pix_fmt yuv420p10le -f yuv4mpegpipe - | x265.exe --preset faster --profile main10 --level-idc 5.1 --output-depth 10 --master-display "G(13250,34500)B(7500,3000)R(34000,16000)WP(15635,16450)L(40000000,50)" --colorprim bt2020 --colormatrix bt2020nc --transfer smpte2084 --max-cll "****,****" --deblock -1:-1 --ctu 64 --bitrate=5000 --vbv-bufsize=5500 --pbratio 1.2 --cbqpoffs -2 --crqpoffs -2 --no-sao --me 3 --subme 3 --merange 57 --b-intra --no-rect --no-amp --ref 4 --weightb --keyint 300 --min-keyint 1 --bframes 4 --aq-mode 1 --aq-strength 0.9 --rd 4 --psy-rd 2.0 --psy-rdoq 3.0 --rdoq-level 2 --no-open-gop --rc-lookahead 80 --scenecut 40 --qcomp 0.60 --no-strong-intra-smoothing --fps 24000/1001 --hdr --hdr-opt --hrd --frames 2301 --y4m --output 输出文件名.hevc -
【参数设置说明】:
--qcomp 作用是处理所有帧的复杂度情况,如果视频高动态特别多的话,mbtree=0的情况下,提升qcomp的取值(高于0.60)是对整体都有好处的。如果视频静态特别多的话,mbtree=0的情况下,保持qcomp=0.60(或低于0.60)就可以了。因为一般视频动态也有,静态也有,保持默认的0.60似乎是最好的。
--mbtree 是处理单独的宏观的复杂度,默认状态下 mbtree=0
--deblock 图像去块,保留更多细节
--ctu 视频图像编码树单元CTU,尺寸越大,分割深度越大,编码效率越高
--pbratio 修改P帧与B帧平均量化值的比例。值越高,B帧的质量越低。
--rdoq-level 水平补偿
删除一下代码可以提高编码速度:
--pbratio 1.2 --cbqpoffs -2 --crqpoffs -2 --no-sao --me 3 --subme 3 --merange 57 --b-intra --no-rect --no-amp --ref 4 --weightb --keyint 300 --min-keyint 1 --bframes 4 --aq-mode 1 --aq-strength 0.9 --rd 4 --psy-rd 2.0 --psy-rdoq 3.0 --rdoq-level 2 --no-open-gop --rc-lookahead 80 --scenecut 40 --qcomp 0.60 --no-strong-intra-smoothing
G(13250,34500)B(7500,3000)R(34000,16000)WP(15635,16450),等参数一般为固定值;
--max-cll "****,****" 中的 ****,**** 需根据实际改为原视频对应参数
“L”控制显示亮度参数设置案列如下(需根据实际改为原视频对应参数):
当其中命令参数为 L(10000000,50) 读取显示参数为 min: 0.0050 cd/m2, max: 1000.0000 cd/m2
当其中命令参数为 L(12000000,500) 读取显示参数为 min: 0.0500 cd/m2, max: 1200.0000 cd/m2
【ffmpeg程序安装方法】
1、解压在官方网站下载好的ffmpeg文件包(已编译版本,如需压制输出10bit视频,则需使用10bit版本的ffmpeg文件),将其中bin文件夹内的ffmpeg.exe、ffplay.exe、ffprobe.exe三个程序复制到电脑系统的WindowsSystem32文件夹中。
2、win+R键输入cmd打开命令提示符,然后在其中输入 ffmpeg –version 如果命令提示符中弹出FFmpeg的版本信息,表示程序安装成功并可正常使用。
3、将x265编码程序(如需压制输出10bit视频,则需使用10bit版本的x265编码程序)与原视频文件放在硬盘同一分区根目录中;
4、案列:比如需转码硬盘D:分区中的视频,则在命令提示符中输入 cd/ 确认后跳转到C:>,再输入d: 确认后跳转到D:> ,然后即可输入相关转码命令进行转码。
13 ffmpeg 编译为 debug模式
--enable-debug=3
--disable-optimizations
--disable-asm
--disable-stripping
14 --preset 和 --tune
鉴于x264的参数众多,各种参数的配合复杂,为了使用者方便,x264建议如无特别需要可使用preset和tune设置。这套开发者推荐的参数较为合理,可在此基础上在调整一些具体参数以符合自己需要,手动设定的参数会覆盖preset和tune里的参数。
--preset的参数主要调节编码速度和质量的平衡,有ultrafast、superfast、veryfast、faster、fast、medium、slow、slower、veryslow、placebo这10个选项,从快到慢。
--tune的参数主要配合视频类型和视觉优化的参数,或特别的情况。如果视频的内容符合其中一个可用的调整值又或者有其中需要,则可以使用此选项,否则建议不使用(如tune grain是为高比特率的编码而设计的)。
tune的值有: film: 电影、真人类型;
animation: 动画;
grain: 需要保留大量的grain时用;
stillimage: 静态图像编码时使用;
psnr: 为提高psnr做了优化的参数;
ssim: 为提高ssim做了优化的参数;
fastdecode: 可以快速解码的参数;
zerolatency:零延迟,用在需要非常低的延迟的情况下,比如电视电话会议的编码。
ffmpeg 设置meta 信息 ( 色域 亮度映射函数 )
ffmpeg -i TravelXP_4K_HDR_HLG.ts -color_primaries 9 -colorspace 9 -color_trc 16 TravelXP_4K_HDR_HLG_drophlgcurv.ts
上面是设置为 bt2020 色域 OETF使用smpte2084
/** * Chromaticity coordinates of the source primaries. */ enum AVColorPrimaries { AVCOL_PRI_RESERVED0 = 0, AVCOL_PRI_BT709 = 1, ///< also ITU-R BT1361 / IEC 61966-2-4 / SMPTE RP177 Annex B AVCOL_PRI_UNSPECIFIED = 2, AVCOL_PRI_RESERVED = 3, AVCOL_PRI_BT470M = 4, ///< also FCC Title 47 Code of Federal Regulations 73.682 (a)(20) AVCOL_PRI_BT470BG = 5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM AVCOL_PRI_SMPTE170M = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC AVCOL_PRI_SMPTE240M = 7, ///< functionally identical to above AVCOL_PRI_FILM = 8, ///< colour filters using Illuminant C AVCOL_PRI_BT2020 = 9, ///< ITU-R BT2020 AVCOL_PRI_SMPTE428 = 10, ///< SMPTE ST 428-1 (CIE 1931 XYZ) AVCOL_PRI_SMPTEST428_1 = AVCOL_PRI_SMPTE428, AVCOL_PRI_SMPTE431 = 11, ///< SMPTE ST 431-2 (2011) / DCI P3 AVCOL_PRI_SMPTE432 = 12, ///< SMPTE ST 432-1 (2010) / P3 D65 / Display P3 AVCOL_PRI_JEDEC_P22 = 22, ///< JEDEC P22 phosphors AVCOL_PRI_NB ///< Not part of ABI }; /** * Color Transfer Characteristic. */ enum AVColorTransferCharacteristic { AVCOL_TRC_RESERVED0 = 0, AVCOL_TRC_BT709 = 1, ///< also ITU-R BT1361 AVCOL_TRC_UNSPECIFIED = 2, AVCOL_TRC_RESERVED = 3, AVCOL_TRC_GAMMA22 = 4, ///< also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM AVCOL_TRC_GAMMA28 = 5, ///< also ITU-R BT470BG AVCOL_TRC_SMPTE170M = 6, ///< also ITU-R BT601-6 525 or 625 / ITU-R BT1358 525 or 625 / ITU-R BT1700 NTSC AVCOL_TRC_SMPTE240M = 7, AVCOL_TRC_LINEAR = 8, ///< "Linear transfer characteristics" AVCOL_TRC_LOG = 9, ///< "Logarithmic transfer characteristic (100:1 range)" AVCOL_TRC_LOG_SQRT = 10, ///< "Logarithmic transfer characteristic (100 * Sqrt(10) : 1 range)" AVCOL_TRC_IEC61966_2_4 = 11, ///< IEC 61966-2-4 AVCOL_TRC_BT1361_ECG = 12, ///< ITU-R BT1361 Extended Colour Gamut AVCOL_TRC_IEC61966_2_1 = 13, ///< IEC 61966-2-1 (sRGB or sYCC) AVCOL_TRC_BT2020_10 = 14, ///< ITU-R BT2020 for 10-bit system AVCOL_TRC_BT2020_12 = 15, ///< ITU-R BT2020 for 12-bit system AVCOL_TRC_SMPTE2084 = 16, ///< SMPTE ST 2084 for 10-, 12-, 14- and 16-bit systems AVCOL_TRC_SMPTEST2084 = AVCOL_TRC_SMPTE2084, AVCOL_TRC_SMPTE428 = 17, ///< SMPTE ST 428-1 AVCOL_TRC_SMPTEST428_1 = AVCOL_TRC_SMPTE428, AVCOL_TRC_ARIB_STD_B67 = 18, ///< ARIB STD-B67, known as "Hybrid log-gamma" AVCOL_TRC_NB ///< Not part of ABI }; /** * YUV colorspace type. */ enum AVColorSpace { AVCOL_SPC_RGB = 0, ///< order of coefficients is actually GBR, also IEC 61966-2-1 (sRGB) AVCOL_SPC_BT709 = 1, ///< also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B AVCOL_SPC_UNSPECIFIED = 2, AVCOL_SPC_RESERVED = 3, AVCOL_SPC_FCC = 4, ///< FCC Title 47 Code of Federal Regulations 73.682 (a)(20) AVCOL_SPC_BT470BG = 5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601 AVCOL_SPC_SMPTE170M = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC AVCOL_SPC_SMPTE240M = 7, ///< functionally identical to above AVCOL_SPC_YCGCO = 8, ///< Used by Dirac / VC-2 and H.264 FRext, see ITU-T SG16 AVCOL_SPC_YCOCG = AVCOL_SPC_YCGCO, AVCOL_SPC_BT2020_NCL = 9, ///< ITU-R BT2020 non-constant luminance system AVCOL_SPC_BT2020_CL = 10, ///< ITU-R BT2020 constant luminance system AVCOL_SPC_SMPTE2085 = 11, ///< SMPTE 2085, Y'D'zD'x AVCOL_SPC_NB ///< Not part of ABI };
16 ffmpeg 硬解+硬编 命令
$runexe -hwaccel cuvid -c:v h264_cuvid -i $src -vf scale_npp=w=1280:h=720 -c:v h264_nvenc $dst
17 ffmpeg 获取硬解cuda 上下文
AVHWFramesContext *frames_ctx = (AVHWFramesContext*)inlink->hw_frames_ctx->data;
AVCUDADeviceContext *hwctx = (AVCUDADeviceContext *)frames_ctx->device_ctx->hwctx;
ffmpeg gdb 打印硬解像素格式
((AVHWFramesContext*)frame->hw_frames_ctx->data)->sw_format
18 ffmpeg 硬解函数: nvenc.c
19 ffmpeg
AVPixFmtDescriptor
static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { ...... [AV_PIX_FMT_P010LE] = { .name = "p010le", .nb_components = 3, // 一共三个分量:Y、U、V .log2_chroma_w = 1, // 水平采样因子是 2,pow(2, 1) .log2_chroma_h = 1, // 垂直采样因子是 2,pow(2, 1) .comp = { { // Y 分量 0, // plane: plane 0, YYYYYYYY... 2, // step: 两个 Y 相距 2 字节 0, // offset: 0 6, // shift: 10 位数据按高位对齐,低 6 位是无效值 10, // depth: 10 位宽 1, 9, 1 }, { // U 分量 1, // plane: plane 1, UVUVUVUV... 4, // step: 两个 U 相距 4 字节 0, // offset: U 在前 V 在后 6, // shift: 10 位数据按高位对齐,低 6 位是无效值 10, // depth: 10 位宽 3, 9, 1 }, { // V 分量 1, // plane: plane 1, UVUVUVUV... 4, // step: 两个 V 相距 4 字节 2, // offset: U 在前 V 在后,因 V 前有 2 个字节被 U 占了 6, // shift: 10 位数据按高位对齐,低 6 位是无效值 10, // depth: 10 位宽 3, 9, 3 }, }, .flags = AV_PIX_FMT_FLAG_PLANAR, }, ...... }