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 \n"); 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三個程序復制到電腦系統的Windows\System32文件夾中。
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, }, ...... }
ffmpeg 打印 rgb->yuv coffs
float coffs[9]; int k; fprintf(stderr,"\nRGB2YUV COFFS:\n"); for( k=0; k!=9; ++k ){ float div_val = k <3 ? 219 : 224; coffs[k] = (c->input_rgb2yuv_table[k]/(double)((1 << RGB2YUV_SHIFT))) * 255.0/ div_val; fprintf(stderr, "%.4f ", coffs[k]); if( (k+1)%3 == 0 ) fprintf(stderr, "\n"); }
FFMPEG 內部YCbCr->R’G’B’的部分代碼 (色彩空間選擇的過程, 默認選擇第二種 BT601)
/* Color space conversion coefficients for YCbCr -> RGB mapping. * Entries are {crv, cbu, cgu, cgv} * crv = (255 / 224) * 65536 * (1 - cr) / 0.5 * cbu = (255 / 224) * 65536 * (1 - cb) / 0.5 * cgu = (255 / 224) * 65536 * (cb / cg) * (1 - cb) / 0.5 * cgv = (255 / 224) * 65536 * (cr / cg) * (1 - cr) / 0.5 * where Y = cr * R + cg * G + cb * B and cr + cg + cb = 1. */ const int32_t ff_yuv2rgb_coeffs[11][4] = { { 117489, 138438, 13975, 34925 }, /* no sequence_display_extension */ { 117489, 138438, 13975, 34925 }, /* ITU-R Rec. 709 (1990) */ { 104597, 132201, 25675, 53279 }, /* unspecified */ { 104597, 132201, 25675, 53279 }, /* reserved */ { 104448, 132798, 24759, 53109 }, /* FCC */ { 104597, 132201, 25675, 53279 }, /* ITU-R Rec. 624-4 System B, G */ { 104597, 132201, 25675, 53279 }, /* SMPTE 170M */ { 117579, 136230, 16907, 35559 }, /* SMPTE 240M (1987) */ { 0 }, /* YCgCo */ { 110013, 140363, 12277, 42626 }, /* Bt-2020-NCL */ { 110013, 140363, 12277, 42626 }, /* Bt-2020-CL */ }; const int *sws_getCoefficients(int colorspace) { if (colorspace > 10 || colorspace < 0 || colorspace == 8) colorspace = SWS_CS_DEFAULT; return ff_yuv2rgb_coeffs[colorspace]; }
編譯 ffmpeg 出現 undefined reference to `x264_bit_depth'
make clean 后重新編譯即可
ffmpeg 使用static 鏈接后出現dlopen 崩潰的解決辦法 用動態編譯 別用靜態了
LD ffprobe_g
libavcodec/libavcodec.a(cuviddec.o): In function `cuvid_load_functions':
/usr/local/include/ffnvcodec/dynlink_loader.h:342: warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
libavformat/libavformat.a(rtsp.o): In function `get_sockaddr':
/data/luoyinjie/rc/vxcode-vod-pipeline_rc/vxcode-vod-pipeline/sources/ffmpeg/libavformat/rtsp.c:206: warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
STRIP ffprobe
libavcodec/libavcodec.a(cuviddec.o): In function `cuvid_load_functions':
/usr/local/include/ffnvcodec/dynlink_loader.h:342: warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
libavformat/libavformat.a(rtsp.o): In function `get_sockaddr':
/data/luoyinjie/rc/vxcode-vod-pipeline_rc/vxcode-vod-pipeline/sources/ffmpeg/libavformat/rtsp.c:206: warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
STRIP ffmpeg
查看 FFmpeg filters 的使用
ffmpeg -h filter=buffersink
ffmpeg 改變視頻的色彩空間
ffmpeg -i 6v0hphj1odgb6lla2om1582531261727.mp4 -vf colorspace=bt2020 -color_range tv -colorspace 9 -color_trc 14 -color_primaries 9 -c:v libyhevc -y 6v0hphj1odgb6lla2om1582531261727_bt2020.mp4
HDR 編碼
ffmpeg -hwaccel cuda -hwaccel_output_format cuda -i NewYork.ts -y -ss 00:00:02 -c:v hevc_nvenc -crf 23 -b:v 30m -colorspace 9 -color_primaries 9 -color_trc 16 ../NewYork_1min.mp4
HDR 編碼的時候編寫元數據
-c:v libx265 \
-x265-params colorprim=bt2020:transfer=smpte2084:colormatrix=bt2020nc:master-display="G(13250,34500)B(7500,3000)R(34000,16000)WP(15635,16450)L(10000000,1)":max-cll=""1000,400"":min-luma=0:max-luma=1000 \
ffplay 播放yuv
ffplay -s 3840x2160 -pix_fmt p010le -f rawvideo ./d89daea7d59e462ef4ce9a2322bb9663_video_000.yuv
19 ffmpeg 遇到錯誤的排查方法
Impossible to convert between the formats supported by the filter 'graph 0 input from stream 0:0' and the filter 'auto_scaler_0'
-v trace 打印信息, 可以看到輸入的格式是 pixfmt:yuv444p12le , filter 不支持這種格式