ffmpeg命令分析下【详细分析合集】

本文详细分析了ffmpeg命令的各种参数,包括-pix_fmt、-vf、-map、-f tee、-filter_complex、-map_channel和-vframes等。通过实例展示了如何使用这些参数实现像素格式转换、TCP流拉取、多路流输出、滤镜应用、声道映射和帧限制等功能。同时,还探讨了ffmpeg在处理复杂滤镜和多输入输出流时的内部逻辑。
摘要由CSDN通过智能技术生成

接上篇

ffmpeg命令分析【内容包括】-vf/ac/b:v/r/re/segment/t/ss/output_ts_offset/vn/acc/print/yuv420p/yuv封装mp4/FFmpeg硬件加速/pix_fmt/拉取TCP流/tee输出多路流/ffmpeg复杂滤镜filter_complex/map_channel/vframe

16、ffmpeg命令分析-pix_fmt

16、ffmpeg命令分析-pix_fmt

本系列 以 ffmpeg4.2 源码为准,下载地址:链接:百度网盘 提取码:g3k8

本系列主要分析各种 ffmpeg 命令参数 在代码里是如何实现的。a.mp4下载链接:百度网盘,提取码:nl0s 。

命令如下:

ffmpeg -vcodec h264 -i a.mp4 -pix_fmt nv12 -vcodec h264_mf -acodec copy a_h264_nvenc.mp4 -y

上面的命令是解码,然后编码,本文不关注编解码,主要分析 -pix_fmt nv12 参数,由于一些硬件编码器只支持特定的像素格式,所以需要 --pix_fmt 指定编码器的 pix_fmt,代码如下:

MATCH_PER_STREAM_OPT(frame_pix_fmts, str, frame_pix_fmt, oc, st);
//省略代码。
if (frame_pix_fmt && (video_enc->pix_fmt = av_get_pix_fmt(frame_pix_fmt)) == AV_PIX_FMT_NONE) {
    av_log(NULL, AV_LOG_FATAL, "Unknown pixel format requested: %s.\n", frame_pix_fmt);
    exit_program(1);
}

 相关视频推荐

FFmpeg最佳学习方法,只讲一次!/FFmpeg/webRTC/rtmp/hls/rtsp/ffplay/srs

重点代码是 video_enc->pix_fmt = av_get_pix_fmt(frame_pix_fmt),命令行的 pix_fmt 最后解析给编码器的 pix_fmt 。

这里,还有一个重点,如果解码器输出的 pix_fmt 跟 video_enc->pix_fmt 不一致,就会创建 filter,进行格式转换。把像素格式转换好之后再丢给编码器。

代码如下:

configure_output_video_filter() 函数代码
 

if ((pix_fmts = choose_pix_fmts(ofilter))) {
        AVFilterContext *filter;
        snprintf(name, sizeof(name), "format_out_%d_%d",
                 ost->file_index, ost->index);
        ret = avfilter_graph_create_filter(&filter,
                                           avfilter_get_by_name("format"),
                                           "format", pix_fmts, NULL, fg->graph);
        av_freep(&pix_fmts);
        if (ret < 0)
            return ret;
        if ((ret = avfilter_link(last_filter, pad_idx, filter, 0)) < 0)
            return ret;
​
        last_filter = filter;
        pad_idx     = 0;
    }

17、ffmpeg命令分析-拉取TCP流

TCP推流命令如下:

ffmpeg.exe -re -i a.mp4 -c copy -f flv tcp://127.0.0.1:1234/live/stream

TCP拉流命令如下:

ffmpeg.exe -listen 1 -i tcp://127.0.0.1:1234/live/stream -c copy -f flv output.flv -y

ffmpeg 除了支持 RTMP,HTTP 等高层的协议,也支持直接拉取 TCP 流。本文主要分析 TCP 拉流的逻辑,推流不管。

-i tcp://127.0.0.1:1234/live/stream 这个参数其实没有太多需要分析的地方,在API调用层,跟 -i 本地文件是一样的,就是传递个字符串进去 avforamt_open_input 函数里面。avforamt_open_input 内部根据字符串类型 做不同的解封装处理,如图:

 主要分析 -listen 1 会影响哪些逻辑。 listen 的定义是在 libavformat/tcp.c 里面,如下:

static const AVOption options[] = {
    { "listen","Listen for incoming connections",  OFFSET(listen),AV_OPT_TYPE_INT, { .i64 = 0 },0, 2,.flags = D|E }
    省略代码...
};

因为 listen 定义是在 libavformat 目录里面的,所以这个 -listen 的解析,是走的 opt_default() -> avformat_get_class() ,最后把 listen 解析到 o->g->format_opts ,然后丢进去 avformat_open_input() 函数,具体分析可以看专栏《FFmpeg源码分析-参数解析篇》

所以 -listen 1 对 ffmpeg.c 的代码逻辑并没有什么影响,他只是 tcp format 的一个 option 参数,传递进去 avformat_open_input() 函数,内部已经封装好,API调用层无感知。


分享一个音视频高级开发交流群,需要C/C++ Linux服务器架构师学习资料加企鹅群:788280672获取资料包括(C/C++,Linux,FFmpeg  webRTC  rtmp  hls rtsp ffplay  srs 等等),免费分享。

 

18、ffmpeg命令分析-tee输出多路流

早期 FFmpeg 在 转 码 后 输出 直播 流 时并 不支持 编码 一次 之后 同时 输出 多路 直播 流, 需要 使用 管道 方式 进行 输出, 而在 新版本 的 FFmpeg 中 已经 支持 tee 文件 封装 及 协议 输出, 可以 使用 tee 进行 多路 流 输出, 本节 将 主要 讲解 管道 方式 输出 多路 流 与 tee 协议 输出 方式 输出 多路 流。
 

本文主要讲解 tee 方式 输出多路流 在 ffmpeg.c 里面的逻辑实现,命令如下:

ffmpeg.exe -re -i a.mp4 -vcodec h264_mf -acodec aac -map 0 -f tee "[f=flv]tcp://127.0.0.1:1234/live/stream | [f=flv]rtmp://192.168.0.122/live/livestream"


上面的命令 音频编码 为 AAC,视频编码为 H264,转成 flv 的封装,然后推了两路流。

1,tcp 流,把 flv 的数据放在 tcp 包里面进行传输。

2,rtmp 流,把flv 的数据放在 rtmp 上层进行传输。

这两路流的服务器请自行搭建。

首先分析 -map 0 参数在 ffmpeg.c 里面的逻辑,map 的定义在 ffmpeg_opt.c 里面。
 

{ "map",            HAS_ARG | OPT_EXPERT | OPT_PERFILE |
                    OPT_OUTPUT,                                  { .func_arg = opt_map },
    "set input stream mapping",
    "[-]input_file_id[:stream_specifier][,sync_file_id[:stream_specifier]]" },

"[-]input_file_id[:stream_specifier][,sync_file_id[:stream_specifier]]" 这句注释,我也没看出这个 map 的具体用法,所以直接分析代码逻辑,从代码逻辑推导出 map的 具体用法。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值