音视频开发项目-2主函数

从主函数开始看起

上一篇定了地图,这篇正式进代码。入口是 rv1126_ffmpeg_main.cpp,整个文件只有 35 行,但我在这 35 行上花的时间比想象中多------因为程序的生命周期全在这里了

一、先把代码全贴出来

cpp 复制代码
#include "rkmedia_ffmpeg_config.h"
#include "ffmpeg_video_queue.h"
#include "rkmedia_module_function.h"
#include "rkmedia_assignment_manage.h"

VIDEO_QUEUE * high_video_queue = NULL;
VIDEO_QUEUE * low_video_queue = NULL;

int main(int argc, char *argv[])
{
    if(argc < 5)
    {
        printf("Please Input ./rv1126_ffmpeg_main high_stream_type high_url_address low_stream_type low_url_address. Notice URL_TYPE: 0-->FLV  1-->TS\n");
        return -1;
    }

    int high_protocol_type = atoi(argv[1]);
    char * high_network_address = argv[2];

    int low_protocol_type = atoi(argv[3]);
    char * low_network_address = argv[4];

    high_video_queue = new VIDEO_QUEUE(); //初始化所有VIDEO队列
    low_video_queue = new VIDEO_QUEUE();

    init_rkmedia_module_function();  //初始化所有rkmedia的模块
    init_rv1126_first_assignment(high_protocol_type, high_network_address,
                                 low_protocol_type, low_network_address);  //开启推流任务

    while (1)
    {
       sleep(20);
    }

    return 0;
}

二、四个参数:两路流各配一个

bash 复制代码
./rv1126_ffmpeg_main <high_stream_type> <high_url> <low_stream_type> <low_url>
# 例如
./rv1126_ffmpeg_main 0 rtmp://192.168.1.100/live/high 0 rtmp://192.168.1.100/live/low

参数是"高清 + 低清"两两一组,每组是 协议类型 + 推流地址

  • 协议类型 0 → FLV(走 RTMP)
  • 协议类型 1 → TS(理论上走 SRT,实际还没搞定,后面说)

第一遍看的时候我有个疑问:为啥要两路流? 后来想明白了,这就是直播行业的标配------观众网速好的看 1080P,网速差的看 720P,服务端按需分发。硬件上就是"一次采集、两路编码"。

三、两个全局队列

cpp 复制代码
VIDEO_QUEUE * high_video_queue = NULL;
VIDEO_QUEUE * low_video_queue = NULL;

注意这两个是全局变量 ,而且后面 rkmedia_data_process.cpp 里是用 extern 引用的:

cpp 复制代码
extern VIDEO_QUEUE *high_video_queue;
extern VIDEO_QUEUE *low_video_queue;

这是 C/C++ 里跨文件共享全局变量的经典写法(声明和定义分离)。全局变量当然不算优雅,但在这个项目里它降低了参数在七八个线程之间传递的复杂度------所有线程都直接认识这两个队列。先跑通再优雅,嵌入式项目里挺常见的选择。

队列在这里 new 出来之后,硬件侧的线程往里塞数据,推流侧的线程从里取数据。它是整个项目的"传送带",第 6 篇专门拆。

四、三步初始化

cpp 复制代码
init_rkmedia_module_function();   // 第一步
init_rv1126_first_assignment(...); // 第二步
while (1) sleep(20);              // 第三步
步骤 函数 在哪个文件 干的事
1 init_rkmedia_module_function() rkmedia_module_function.cpp 系统初始化 + VI/VENC/RGA 全部配好参数
2 init_rv1126_first_assignment() rkmedia_assignment_manage.cpp FFmpeg 初始化 + 通道绑定 + 创建所有工作线程
3 主循环 sleep 本文件 什么都不干,纯活着

分工很清楚:第一步把硬件"摆好",第二步把数据流的"管道"接起来并放水,第三步主线程退到一边看着

这里有个值得咂摸的点:主线程 while(1) sleep(20) 为什么不 join 线程?因为所有工作线程创建时都调了 pthread_detach(pthread_self())(后面篇会看到),分离线程 ------线程自己结束后资源自动回收,不需要别人 join。所以主线程唯一的作用就是"别让进程退出"。嵌入式设备上的常驻程序基本都是这个套路。

五、我卡过的一个点:函数名里的 "assignment"

init_rv1126_first_assignment 这个名字我盯着看了半天。assignment?任务?作业?

看完实现才明白,这里把"一轮推流任务"叫做一个 assignment:给两路流各建一套 FFmpeg 输出上下文,把 VI/VENC/RGA 通道绑起来,再创建 5 个工作线程。名字里的 "first" 暗示设计者本来可能想做多任务管理(跑多个 assignment),但目前只实现了这一个。猜的,没证据,先记着。

六、小结

main 函数虽短,但把三件事定了调:

  1. 两路码流的架构(参数形式就暴露了)
  2. 全局队列做 RKMedia 和 FFmpeg 的衔接
  3. 主线程只负责活着,所有活都在分离线程里干

下一篇进第一站:init_rkmedia_module_function(),看 VI、VENC、RGA 这三个模块的参数是怎么配的------1920x1080、25fps、CBR 码率这些数字都在那里。


本篇对应源码:rv1126_ffmpeg_main.cpp(全文 35 行)

相关推荐
m0_614523551 天前
普通视频怎么做多场景一镜到底:路线设计、逐段衔接与整体验收
人工智能·音视频
Pocker_Spades_A1 天前
视频不用再一张张截图:ClipSketch AI 把关键画面转成漫画,还能顺手生成文案
人工智能·音视频
星辰徐哥1 天前
本地视频预览别只自己看:把Remotion动效项目发给客户远程验收
docker·ai·node.js·html·音视频·react·remotion
镜像视界(浙江)科技有限公司1 天前
《视频孪生之上:二维展示终结,三维空间计算重构城市逻辑》——跨摄像连续表达 × 三角测量厘米级定位 × 动态轨迹建模,构建新一代城市空间
大数据·人工智能·算法·矩阵·音视频·空间计算
你不是我我1 天前
【AI 测评】想用自己的声音给视频配音?Index-TTS本地部署这样做
人工智能·音视频
Ulyanov1 天前
AudioVision Pro:基于 PySide6 + sounddevice 的实时音频可视化播放器设计
python·算法·音视频
福大大架构师每日一题1 天前
ComfyUI v0.34.0发布:视频、音频、三维、显存与合作节点全面更新
音视频
敲代码的嘎仔1 天前
用 Redis 合并写 + DelayQueue 延迟检测,把视频播放进度写库频率降到 1/60
java·开发语言·数据库·redis·缓存·音视频·高并发
Xxtaoaooo1 天前
AI 视频生成能不能真正跑通?MoneyPrinterTurbo 本地制作、远程访问与授权验证
人工智能·音视频·cpolar·ai视频·自动化短视频
bloxed2 天前
“视频上看得见的洪水淹没预演”:视频数字孪生完整实践
音视频