FFMPEG输出模块初始化

1.本章节内容:

FFMPEG输出模块的最大作用是对音视频推流模块进行初始化让其能够正常工作起来,RV1126的码流通过FFMPEG进行推流,输出模块一般由几个步骤。分别由avformat_alloc_output_context2分配AVFormatContextavformat_new_stream初始化AVStream结构体、avcodec_find_encoder找出对应的codec编码器、利用avcodec_alloc_context3分配AVCodecCotext、设置AVCodecContext结构体参数、利用avcodec_parameters_from_context把codec参数传输到AVStream里面的参数、avio_open初始化FFMPEG的IO结构体、avformat_write_header初始化AVFormatContext

2.FFMPEG 输出配置的框图

2.1. 分配F FMPEG AVFormatContext 输出的上下文结构体指针

int avformat_alloc_output_context2(AVFormatContext **ctx, AVOutputFormat *oformat, const char *format_name, const char *filename)

第一个传输参数: AVFormatContext结构体指针的指针,是存储音视频封装格式中包含的信息的结构体,所有对文件的封装、编码都是从这个结构体开始。

第二个传输参数: AVOutputFormat的结构体指针,它主要存储复合流信息的常规配置,默认为设置NULL。

第三个传输参数: format_name指的是复合流的格式,比方说:flv、ts、mp4等等

第四个传输参数: filename是输出地址,输出地址可以是本地文件(如:xxx.mp4、xxx.ts等等)。也可以是网络流地址(如:rtmp://xxx.xxx.xxx.xxx:1935/live/01)

上面这个API是根据我们流媒体类型去分配AVFormatContext 结构体。我们传进来的类型会分为FLV_PROTOCOLTS_PROTOCOL ,具体如何配置如下面:

TS_PROTOCOL 类型 :avformat_alloc_output_context2(&group->oc, NULL, "mpegts ", group->url_addr);

FLV_PROTOCOL 类型 :avformat_alloc_output_context2(&group->oc, NULL, "flv" , group->url_addr);

注意:TS格式分别可以适配以下流媒体复合流,包括:SRT、UDP、TS本地文件等。flv格式包括:RTMP、FLV本地文件等等。

2 .2. 配置推流器编码参数和A VStream 结构体

A VS tream 主要是存储流信息结构体,这个流信息包含音频流和视频流。创建的API是avformat_new_stream 如下图****:****

AVS tream * avformat _new_stream(AVFormatContext *s, AVDictionary **options);

第一个传输参数: AVFormatContext的结构体指针

第二个传输参数: AVDictionary结构体指针的指针

返回值: AVStream结构体指针

2.3. 设置对应的推流器编码器参数

AVCodec *avcodec_find_encoder(enum AVCodecID id); / /

第一个传输参数: 传递参数AVCodecID

2.4. 根据编码器ID分配 AVCodecContext 结构体

AVCodecContext *avcodec_alloc_context3(const AVCodec *codec);

****第一个参数:****传递AVCodec结构体指针

avcodec_find_encoder 的主要作用是通过codec_id (编码器id )找到对应的AVCodec 结构体。在RV1126推流项目中c odec_id 我们使用两种,分别是AV_CODEC_ID_H264AV_CODEC_ID_H265 并利用a vcodec_alloc_context3 去创建AVCodecContext上下文。

初始化完A VS tream和编码上下文结构体之后,我们就需要对这些参数进行配置。重点:推流编码器参数和RV1126编码器的参数要完全一样,否则可能会出问题,具体的如下图:

1920 * 1080编码器和FFMPEG推流器的配置

1280* 720编码器和FFMPEG推流器的配置

FFMPEG的视频编码参数如:分辨率(WIDTHH EIGHT )、时间基(time_base )、 帧率(r_frame_rate )、GOP_SIZE等都需要和右边VENC的参数要一一对应起来。其中time_base的值要和视频帧率必须要一致。如RV1126高编码器分辨率是1920 * 1080,则FFMPEG推流器的WIDTH = 1920,HEIGHT = 1080;若RV1126编码器的分辨率是1280 * 720,则FFMPEG推流器的WIDTH = 1280,HEIGHT = 720;若RV1126的GOP的值是25,那右边FFMPEG的gop_size 也等于25;time_base的数值和帧率保持一致

AV_CODEC_FLAG_GLOBAL_HEADER ****:****发送视频数据的时候都会在关键帧前面添加SPS/PPS,这个标识符在FFMPEG初始化的时候都需要添加。

2.5. 设置完上述参数之后, 拷贝参数到AVStream编解码器 ,具体的操作如下:

拷贝参数到AVStream,我们封装到open_video自定义函数里面,要先调用avcodec_open2打开编码器,然后再调用avcodec_parameters_from_context把编码器参数传输到AVStream里面

2.5.1.int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options);

这个函数的具体作用是, 打开编解码器

****第一个参数:****AVCodecContext结构体指针

****第二个参数:****AVCodec结构体指针

****第三个参数:****AVDictionary二级指针

2.5.2. int avcodec_parameters_from_context(AVCodecParameters *par, const AVCodecContext *codec);

这个函数的具体作用是,把 AVCodecContext 的参数拷贝到 AVCodecParameters 里面。

****第一个参数:****AVCodecParameters结构体指针

****第二个参数:****AVCodecContext结构体指针

2.6 . 打开I O 文件操作

使用avio_open 打开对应的文件,注意这里的文件不仅是指本地的文件也指的是网络流媒体文件,下面是a vio_open的定义。

int avio_open(AVIOContext **s, const char *url, int flags);

****第一个参数:****AVIOContext的结构体指针,它主要是管理数据输入输出的结构体

第二个参数: url地址,这个URL地址既包括本地文件如(xxx.ts、xxx.mp4),也可以是网络流媒体地址,如(rtmp://192.168.22.22:1935/live/01)等

****第三个参数:****flags标识符

#define AVIO_FLAG_READ 1 /**< read-only */

#define AVIO_FLAG_WRITE 2 /**< write-only */

#define AVIO_FLAG_READ_WRITE (AVIO_FLAG_READ|AVIO_FLAG_WRITE) /**< read-write pseudo flag */

2.7 . avformat_write_header 对头部进行初始化 输出模块头部进行初始化

int avformat_write_header(AVFormatContext *s, AVDictionary **options);

第一个参数: 传递AVFormatContext结构体指针

第二个参数: 传递AVDictionary结构体指针的指针

相关推荐
天空'之城3 小时前
Linux 系统编程 21:守护进程与日志系统全解
linux·系统编程·日志系统·守护进程
l1t4 小时前
用split命令恢复被wget -c命令误追加的zip压缩包
linux
辉灰笔记5 小时前
MySQL8 意外关机/误移data目录导致服务启动失败 PID报错/权限报错 修复文档
linux·数据库·mysql·centos
ylscode7 小时前
CVE-2026-31694 漏洞深度分析:Linux 内核 FUSE 组件存在本地提权风险,普通用户可直取 root 权限
linux·运维·服务器
无足鸟ICT8 小时前
【RHCA+】bash命令
linux·开发语言·bash
weixin_307779138 小时前
Linux下Docker Compose里运行的MySQL数据库故障诊断Shell脚本
linux·运维·mysql·docker·自动化
小生不才yz8 小时前
Shell脚本精读 · S14-02 | 脚本模板:从 20 行工具到可维护项目
linux
x-cmd8 小时前
Linus 9 年前说「模糊测试有效」——今天已成 OSS-Fuzz 时代铁律
linux·ai·rust·开源·自动化·agent·安全性测试
六点_dn9 小时前
Linux学习笔记-chmod命令
linux·笔记·学习
编程令我快乐9 小时前
windows单次传linux文件太大
linux·运维·服务器