P10 RV1126推流项目——ffmpeg输出参数初始化

2024-01-05 00:12

本文主要是介绍P10 RV1126推流项目——ffmpeg输出参数初始化,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 前言 

                             

从本章开始我们将要学习嵌入式音视频的学习了 ,使用的瑞芯微的开发板

🎬 个人主页:@ChenPi

🐻推荐专栏1: 《C++_@ChenPi的博客-CSDN博客》✨✨✨ 

🔥 推荐专栏2: 《Linux C应用编程(概念类)_@ChenPi的博客-CSDN博客》✨✨✨

🛸推荐专栏3:《嵌入式音视频_@ChenPi的博客-CSDN博客》
🌺本篇简介  :本章主要讲解ffmpeg模块输出参数的初始化

 

今天讲解的部分就是继上章未讲完的部分继续讲解

首先我们看上图红框里面的函数,函数内部就是实现ffmpeg初始化,合成复合流以及推流

里面内容比价多,我可能分为三章去分别讲解,今天我们先讲一下ffmpeg的参数初始化

01  ffmpeg输出模块结构体

在FFMPEG输出模块中用到了很多个结构体,分别是:AVFormatContext、AVStream、AVCodec、AVCodecContext、AVIOContext

  1. AVFormatContext:是存储音视频封装格式中包含的信息的结构体,它是FFMPEG中的核心,所有的文件封装、编码都是从它开始
  2.  AVStream:AVStream主要存储了音频流、视频流的具体信息
  3. ​​​​​​​ AVCodec:AVCodec是存储编解码信息的结构体
  4. ​​​​​​​ AVCodecContext:AVCodecContext 是编解码上下文,它主要的功能是除了存储AVCodec的信息外,还保存了额外的编码属性
  5. AVIOContext:其中AVIOContext是FFMPEG管理输入输出数据的结构体

 02 ffmpeg初始化代码分析

 这个代我们要我们要先从这个结构体开始看

这个结构体会有些许复杂

typedef struct
{AVStream *stream;  /*主要储存了音视频流的具体信息*/AVCodecContext *enc;   //编解码上下文,它主要的功能是除了存储 AVCodec 的信息外,还保存了额外的编码属性int64_t next_timestamp;  //int samples_count;AVPacket *packet;   //压缩后的数据和关于这些数据的一些附加的信息,如显示时间戳(pts),解码时间戳(dts),数据时长(duration),所在流媒体的索引(stream_index)等等。
} OutputStream;typedef struct
{unsigned int config_id;int protocol_type;                    //流媒体TYPEchar network_addr[NETWORK_ADDR_LENGTH];//流媒体地址enum AVCodecID video_codec; //视频编码器IDenum AVCodecID audio_codec; //音频编码器IDOutputStream video_stream; //VIDEO的STREAM配置OutputStream audio_stream; //AUDIO的STREAM配置AVFormatContext *oc; //是存储音视频封装格式中包含的信息的结构体,也是FFmpeg中统领全局的结构体,对文件的封装、编码操作从这里开始。
} RKMEDIA_FFMPEG_CONFIG; //FFMPEG配置

 

这个结构体很重要,这里面保存着配置相关的所有信息

其中最重要的结构体是AVFormatContext,里面存储音视频封装格式中包含的信息的结构体,

也是FFmpeg中统领全局的结构体,对文件的封装、编码操作从这里开始。

 将一些简单的参数配置完后,我们看一下如何初始化FFmpeg

 ffmpeg输出模块初始化大概就是这八步,我们一步一步解析

2.1 根据需要配置码流属性avformat_alloc_output_context2()

函数原型:

int avformat_alloc_output_context2(AVFormatContext **ctx, 
AVOutputFormat *oformat, const char *format_name, const char *filename)
  1. 第一个传输参数:AVFormatContext结构体指针的指针,是存储音视频封装格式中包含的信息的结构体,所有对文件的封装、编码都是从这个结构体开始。
  2. 第二个传输参数:AVOutputFormat的结构体指针,它主要存储复合流信息的常规配置,默认为设置NULL。
  3. 第三个传输参数:format_name指的是复合流的格式,比方说:flv、ts、mp4等等
  4. 第四个传输参数:filename是输出地址,输出地址可以是本地文件(如:xxx.mp4、xxx.ts等等)。也可以是网络流地址(如:rtmp://xxx.xxx.xxx.xxx:1935/live/01)

2.2配置推流器编码参数和AVStream结构体

AVStream主要是存储流信息结构体,这个流信息包含音频流和视频流。

创建的API是avformat_new_stream如下

 函数原型:

AVStream *avformat_new_stream(AVFormatContext *s, const AVCodec *c)
  • 参数1:AVFormatContext的结构体指针
  • 参数2:AVDictionary结构体指针的指针
  • 返回值:成功返回AVStream结构体指针,失败返回NULL

创建输出码流AVStream, AVStream是存储每一个视频/音频流信息的结构体


 2.3找到编码器avcodec_find_encoder

找到对应的编码ID

函数原型:

AVCodec *avcodec_find_encoder(AVCodecID id)

 

  •  参数1:请求编码器的编号
  • 返回值:返回查找到的解码器(没有找到就返回NULL

 2.4 avcodec_alloc_context3分配AVCodecContext结构体

函数原型:

AVCodecContext *avcodec_alloc_context3(const AVCodec *codec)

功能

  • 分配一个AVCodecContext,并将其字段设置为默认值。
  • 结果由avcodec_free_context()释放

参数

  • 如果非null,分配私有数据并初始化给定编解码器的默认值。使用不同的编解码器调用avcodec_open2()是非法的。
  • 如果为NULL,那么特定于编解码器的默认值将不会被初始化,这可能会导致默认设置不理想(这对于编码器(例如libx264)尤为重要)。

返回值

  • 一个用默认值填充的AVCodecContext,失败时为NULL。

 2.5 设置AVCodecContext的参数

 

FFMPEG的视频编码参数如:分辨率(WIDTHHEIGHT)、时间基(time_base)、 帧率(r_frame_rate)、GOP_SIZE等都需要和右边VENC的参数要一一对应起来。其中time_base的值要和视频帧率必须要一致。

FFMPEG的音频编码参数如:音频采样格式(sample_fmt)、音频码率(bit_rate)、 音频采样率(sample_rate)、 音频布局(channel_layout)、 音频通道(channels)、 时间基(time_base)等都需要和右边AENC的参数一一对应。其中time_base的值必须要和音频采样率要一致。

 

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

 2.6 使能推流编码器

这里的open_videoopen_audio就是使能推流编码器,其中avcodec_open2让编码器和编码器上下文进行关联。并用avcodec_parameters_from_context把刚初始化的上下文传输到AVStream的编解码器。

 2.7打开IO文件操作

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

int avio_open(AVIOContext **s, const char *url, int flags);
  1. 第一个参数:AVIOContext的结构体指针,它主要是管理数据输入输出的结构体
  2. 第二个参数: url地址,这个URL地址既包括本地文件如(xxx.ts、xxx.mp4),也可以是网络流媒体地址,如(rtmp://192.168.22.22:1935/live/01)等
  3. 第三个参数: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.8  avformat_write_header对头部进行初始化

int avformat_write_header(AVFormatContext *s, AVDictionary **options);
  • 第一个参数:传递AVFormatContext结构体指针
  • 第二个参数:传递AVDictionary结构体指针的指针

 

这篇关于P10 RV1126推流项目——ffmpeg输出参数初始化的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/571035

相关文章

Python基于wxPython和FFmpeg开发一个视频标签工具

《Python基于wxPython和FFmpeg开发一个视频标签工具》在当今数字媒体时代,视频内容的管理和标记变得越来越重要,无论是研究人员需要对实验视频进行时间点标记,还是个人用户希望对家庭视频进行... 目录引言1. 应用概述2. 技术栈分析2.1 核心库和模块2.2 wxpython作为GUI选择的优

一文教你如何将maven项目转成web项目

《一文教你如何将maven项目转成web项目》在软件开发过程中,有时我们需要将一个普通的Maven项目转换为Web项目,以便能够部署到Web容器中运行,本文将详细介绍如何通过简单的步骤完成这一转换过程... 目录准备工作步骤一:修改​​pom.XML​​1.1 添加​​packaging​​标签1.2 添加

tomcat多实例部署的项目实践

《tomcat多实例部署的项目实践》Tomcat多实例是指在一台设备上运行多个Tomcat服务,这些Tomcat相互独立,本文主要介绍了tomcat多实例部署的项目实践,具有一定的参考价值,感兴趣的可... 目录1.创建项目目录,测试文China编程件2js.创建实例的安装目录3.准备实例的配置文件4.编辑实例的

springboot集成Deepseek4j的项目实践

《springboot集成Deepseek4j的项目实践》本文主要介绍了springboot集成Deepseek4j的项目实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价... 目录Deepseek4j快速开始Maven 依js赖基础配置基础使用示例1. 流式返回示例2. 进阶

一文带你了解SpringBoot中启动参数的各种用法

《一文带你了解SpringBoot中启动参数的各种用法》在使用SpringBoot开发应用时,我们通常需要根据不同的环境或特定需求调整启动参数,那么,SpringBoot提供了哪些方式来配置这些启动参... 目录一、启动参数的常见传递方式二、通过命令行参数传递启动参数三、使用 application.pro

SpringBoot项目启动报错"找不到或无法加载主类"的解决方法

《SpringBoot项目启动报错找不到或无法加载主类的解决方法》在使用IntelliJIDEA开发基于SpringBoot框架的Java程序时,可能会出现找不到或无法加载主类com.example.... 目录一、问题描述二、排查过程三、解决方案一、问题描述在使用 IntelliJ IDEA 开发基于

SpringBoot项目使用MDC给日志增加唯一标识的实现步骤

《SpringBoot项目使用MDC给日志增加唯一标识的实现步骤》本文介绍了如何在SpringBoot项目中使用MDC(MappedDiagnosticContext)为日志增加唯一标识,以便于日... 目录【Java】SpringBoot项目使用MDC给日志增加唯一标识,方便日志追踪1.日志效果2.实现步

基于@RequestParam注解之Spring MVC参数绑定的利器

《基于@RequestParam注解之SpringMVC参数绑定的利器》:本文主要介绍基于@RequestParam注解之SpringMVC参数绑定的利器,具有很好的参考价值,希望对大家有所帮助... 目录@RequestParam注解:Spring MVC参数绑定的利器什么是@RequestParam?@

Spring组件初始化扩展点BeanPostProcessor的作用详解

《Spring组件初始化扩展点BeanPostProcessor的作用详解》本文通过实战案例和常见应用场景详细介绍了BeanPostProcessor的使用,并强调了其在Spring扩展中的重要性,感... 目录一、概述二、BeanPostProcessor的作用三、核心方法解析1、postProcessB

python多种数据类型输出为Excel文件

《python多种数据类型输出为Excel文件》本文主要介绍了将Python中的列表、元组、字典和集合等数据类型输出到Excel文件中,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参... 目录一.列表List二.字典dict三.集合set四.元组tuplepython中的列表、元组、字典