三:FFMPEG拉流读取模块的讲解

news2025/3/12 22:02:51

        FFMPEG拉流读取模块在远程监控项目最核心的作用是读取UVC摄像头传输的H264码流,并对其码流进行帧的提取,提取完成之后则把数据传输到VDEC解码模块进行解码。而在我们这个项目中,UVC推流的功能由FFMPEG的命令完成。 

FFMPEG拉流读取模块的API

        在FFMPEG里面提供了一系列的API对码流进行读取和提取帧,下面我们来看看远程监控项目用到了什么API。

FFMPEG读取模块初始化的API

        在FFMPEG里面,读取模块的初始化用的是avformat_open_input

       int avformat_open_input(AVFormatContext **ps, const char *url, AVInputFormat *fmt, AVDictionary **options);

第一个参数:

        AVFormatContext的结构体二级指针,这个结构体是FFMPEG非常重要的内部桥梁,结构体内部包含有AVInputFormat、AVOutputFormat、AVCodec、AVStream、AVDictionary 、AVClass等重要结构体。

第二个参数:

        url是需要读取的流媒体文件名,这个地址可以是文件如(xxx.mp4、xxx.ts、xxx.flv);也可以是网络流媒体地址,如:(rtmp://192.168.100.22.22:1935/live/01、rtsp://192.168.100.22.22:1935/live/01、udp://192.168.100.66:8080)

第三个参数:

        AVInputFormat结构体指针,AVInputFormat是FFMPEG解复用器对象,它表示的是输入文件容器的格式。通常设置为 NULL,让 FFmpeg 自动检测

第四个参数:

        AVDictionary的二级地址,AVDictionary是FFMPEG的字典结构体,它主要是设置FFMPEG内部的参数,如:video_size分辨率、max_delay最大延迟数等,并且以key-value的方式进行存储。options: 用于传递额外的选项,通常设置为 NULL


FFMPEG获取流媒体具体信息的API

        在FFMPEG里面,获取流媒体具体信息的API是avformat_find_stream_info

        int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options);

第一个参数:

        AVFormatContext结构体指针,这个结构体是FFMPEG非常重要的内部桥梁,它的主要功能是获取FFMPEG解封装的数据,如(flv/mp4/ts)等。

第二个参数:

        AVDictionary的二级地址,AVDictionary是FFMPEG的字典结构体,它主要是设置FFMPEG内部的参数,如:video_size分辨率、max_delay最大延迟数等,并且以key-value的方式进行存储。


FFMPEG查找最佳匹配的流媒体函数API

        这个函数的最主要作用是获取音视频的索引值,就是stream_index。stream_index可以是音频索引也可以是视频索引

int av_find_best_stream(AVFormatContext *ic, enum AVMediaType type,int wanted_stream_nb,int related_stream,AVCodec **decoder_ret,int flags);

第一个参数:AVFormatContext结构体指针,它表示的是输入流媒体的上下文

第二个参数:type类型,这里指的是要查找类型的索引,分别是AVMEDIA_TYPE_VIDEO视频类型、AVMEDIA_TYPE_AUDIO音频类型、AVMEDIA_TYPE_SUBTITLE字幕类型

第三个参数:wanted_stream_nb期望的流媒体索引号,默认是-1

第四个参数:related_stream前一个流媒体索引号,默认-1

第五个参数:返回decoder_ret解码器的指针

第六个参数:flags查找最佳流的标志位,默认是0

返回值:返回最佳的流媒体索引值,也就是音视频的索引值


 FFMPEG读取压缩码流并抽取帧数据的API 

        在FFMPEG里面,使用av_read_frame对压缩裸流进行帧数据的提取,av_read_frame的工作流程如上图,这里重点说一下它的工作流程。H264(或者H265)的裸流数据,一般是以StartCode+NALU(SPS)+StartCode+NALU(PPS)+StartCode+NALU(I)+StartCode+NALU(P)....这种连续的数据表示的,但是对于解码器来说它只能解码一帧单独的数据不能解码连续的数据。

        所以此时,av_read_frame就可以把这一连串的码流进行分割。如上图:第一个StartCode+NALU(SPS),第二个StartCode+NALU(PPS),第三个StartCode+NALU(I),第四个StartCode+NALU(P)被一个一个分割出来,并把这一帧帧分割出来的数据传输到解码器。此时解码器才能够正确解码出数据。

int av_read_frame(AVFormatContext *s, AVPacket *pkt);

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

第二个参数:AVPacket结构体指针


远程监控项目FFMPEG拉流输入模块初始化的代码实现

读取json文件并解析url地址 

        是获取摄像头参数和URL地址的实现过程,是通过JSON文件获取URL地址的实现。这个代码非常简单,利用fopen打开json文件FILE *file = fopen("/www/cjson_dir/network_detail.json", "r"), 并调用fread读取里面的内容, 然后用cJSON的API来解析JSON数据,具体的实现是cJSON *json = cJSON_Parse(data), 并获取JSON文件的URL地址, 具体的实现是cJSON *url_address_json = cJSON_GetObjectItem(json, "url_address"); char *network_address = url_address_json->valuestring。经过这几步,就可以获取URL地址了。

avformat_network_init初始化网络配置

    /**
     * 第二步:
     * 初始化网络库,使用网络库时,必须调用此函数非常重要。
     */
    av_format_network_init();

        用于初始化网络协议。在某些情况下,当你需要通过网络访问音视频资源时,可能需要调用这个函数来确保网络协议的正确初始化.。

avformat_open_input初始化FFMPEG拉流输入模块

  /**
     * 第三步:
     * vformat_open_input,流输入模块
     */
    if ((avformat_open_input(&m_pInFmtCtx, network_address, 0, 0)) < 0)
    {
        printf("文件读取失败\n");
        return -1
    }
    printf("文件读取成功\n");

        是调用avformat_open_input打开输入的AVFormatContext结构体指针(大管家婆), 这里面传入三个参数。第一个传参:AVFormatContext结构体指针; 第二个传参: URL地址, 这里直接从json文件读取; 第三个传参:fmt这里填0即可; 第四个传参: options填0即可。经过上面open操作后,就可以初始化输入的AVFormatContext结构体。

 avformat_find_stream_info获取输入端的消息

    /**
     * 第四步:
     * 找到流的一些消息,采样格式或者分辨率.....
     * 比如获取视频帧率、视频宽高,重新计算最大分析时长,打开解码器解码获取codec数据
     */
    // 把大管家婆传进去,因为打开问的时候,大管家婆已经获取到了所有的消息
    avformat_find_stream_info(m_pInFmtCtx, nullptr);
    printf("流的消息解析完毕\n");

        avformat_find_stream_info获取输入模块的信息,这其中包括视频帧率、视频宽高,重新计算最大分析时长,打开解码器解码获取codec数据。

 av_find_best_stream查找对应的音视频索引值 


    /**
     * 第五步:
     * 通过av_find_best_stream()函数来获取流的索引
     * 第二个参数就是代表着要寻找的流
     * 比如视频的index是0,音频的index是1,后面可能还有字幕流..
     */
    // 把大管家婆传进去,因为打开问的时候,大管家婆已经获取到了所有的消息
    int nvideo_index = av_find_best_stream(m_pInFmtCtx, AVMEDIA_TYPE_VIDEO, -1, -1, nullptr);
    if (nvideo_index < 0)
    {

        avformat_free_context(m_pInFmtCtx);
        return -1;
    }
    // 成功获取视频的索引
    printf("==> av_find_best_stream!\n");

        av_find_best_stream获取音视频的索引值,由于UVC传来的数据只有视频数据,所以只有视频索引。 

整体框架

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2313947.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《苍穹外卖》SpringBoot后端开发项目核心知识点与常见问题整理(DAY1 to DAY3)

目录 一、在本地部署并启动Nginx服务1. 解压Nginx压缩包2. 启动Nginx服务3. 验证Nginx是否启动成功&#xff1a; 二、导入接口文档1. 黑马程序员提供的YApi平台2. YApi Pro平台3. 推荐工具&#xff1a;Apifox 三、Swagger1. 常用注解1.1 Api与ApiModel1.2 ApiModelProperty与Ap…

QT系列教程(20) Qt 项目视图便捷类

视频连接 https://www.bilibili.com/video/BV1XY41127t3/?vd_source8be9e83424c2ed2c9b2a3ed1d01385e9 Qt项目视图便捷类 Qt项目视图提供了一些便捷类&#xff0c;包括QListWidget, QTableWidget&#xff0c; QTreeWidget等。我们分别介绍这几个便捷类。 我们先创建一个Qt …

动态扩缩容引发的JVM堆内存震荡:从原理到实践的GC调优指南

目录 一、典型案例&#xff1a;系统发布后的GC雪崩事件 &#xff08;一&#xff09;故障现象 1. 刚刚启动时 GC 次数较多 2. 堆内存锯齿状波动 3. GC日志特征&#xff1a;Allocation Failure &#xff08;二&#xff09;问题定位 二、原理深度解析&#xff1a;JVM内存弹…

AI智能眼镜主控芯片:技术演进与产业生态的深度解析

一、AI智能眼镜的技术挑战与主控芯片核心诉求 AI智能眼镜作为XR&#xff08;扩展现实&#xff09;技术的代表产品&#xff0c;其核心矛盾在于性能、功耗与体积的三角平衡。主控芯片作为设备的“大脑”&#xff0c;需在有限空间内实现复杂计算、多模态交互与全天候续航&#xf…

微服务拆分-远程调用

我们在查询购物车列表的时候&#xff0c;它有一个需求&#xff0c;就是不仅仅要查出购物车当中的这些商品信息&#xff0c;同时还要去查到购物车当中这些商品的最新的价格和状态信息&#xff0c;跟购物车当中的快照进行一个对比&#xff0c;从而去提醒用户。 现在我们已经做了服…

[网络爬虫] 动态网页抓取 — Selenium 介绍 环境配置

&#x1f31f;想系统化学习爬虫技术&#xff1f;看看这个&#xff1a;[数据抓取] Python 网络爬虫 - 学习手册-CSDN博客 0x01&#xff1a;Selenium 工具介绍 Selenium 是一个开源的便携式自动化测试工具。它最初是为网站自动化测试而开发的&#xff0c;类似于我们玩游戏用的按…

【RAGFlow】windows本地pycharm运行

原因 由于官方只提供了docker部署&#xff0c;基于开源代码需要实现自己内部得逻辑&#xff0c;所以需要本地pycharm能访问&#xff0c;且docker运行依赖得其余组件&#xff0c;均需要使用开发服务器得配置。 修改过程 安装python 项目依赖于Python 版本&#xff1a;>3.1…

树莓派5首次开机保姆级教程(无显示器通过VNC连接树莓派桌面)

第一次开机详细步骤 步骤一&#xff1a;树莓派系统烧录1 搜索打开烧录软件“Raspberry Pi Imager”2 选择合适的设备、系统、SD卡3 烧录配置选项 步骤二&#xff1a;SSH远程树莓派1 树莓派插电2 网络连接&#xff08;有线或无线&#xff09;3 确定树莓派IP地址 步骤三&#xff…

html-表格标签

一、表格标签 1. 表格的主要作用 表格主要用于显示&#xff64;展示数据,因为它可以让数据显示的非常的规整,可读性非常好&#xff61;特别是后台展示数据 的时候,能够熟练运用表格就显得很重要&#xff61;一个清爽简约的表格能够把繁杂的数据表现得很有条理&#xff61; 总…

大模型安全新范式:DeepSeek一体机内容安全卫士发布

2月以来&#xff0c;DeepSeek一体机几乎成为了政企市场AI消费的最强热点。 通过一体机的方式能够缩短大模型部署周期&#xff0c;深度结合业务场景&#xff0c;降低中小企业对于大模型的使用门槛。据不完全统计&#xff0c;已约有超过60家企业基于DeepSeek推出一体机产品。 但…

数据分析绘制随时间顺序变化图加入线性趋势线——numpy库的polyfit计算一次多项式拟合

import pandas as pd import numpy as np import matplotlib.pyplot as plt# 导入数据 data pd.read_csv(rC:\Users\11712\notebooktrain1.csv)# 假设数据包含 date_time 和 speed 列 data[date_time] pd.to_datetime(data[date_time]) # 确保时间列是 datetime 类型 data.s…

密闭空间可燃气体监测终端:守护城市命脉,智驭燃气安全!

近年来&#xff0c;陕西省高度重视燃气安全&#xff0c;出台了一系列政策文件&#xff0c;旨在全面加强城镇燃气安全监管&#xff0c;防范化解重大安全风险。2023年&#xff0c;陕西省安委会印发《全省城镇燃气安全专项整治工作方案》&#xff0c;明确要求聚焦燃气经营、输送配…

阿里千问大模型(Qwen2.5-VL-7B-Instruct)部署

参考链接 知乎帖子 B站视频 huggingface 镜像网站&#xff08;不太全&#xff0c;比如 Qwen/Qwen2.5-VL-7B-Instruct就没有&#xff09; huggingface 5种下载方式汇总 通过huggingface-cli下载模型 不一样的部分是预训练权重的下载和demo 首先安装huggingface_hub pip insta…

【Go学习实战】03-3-文章评论及写文章

【Go学习实战】03-3-文章评论及写文章 文章评论注册valine获取凭证加载评论页面 写文章修改cdn位置完善功能查看页面 发布文章POST发布文章发布文章测试 查询文章详情查询详情测试 修改文章修改文章测试 写文章图片上传前端后端逻辑测试 文章评论 这里我们的博客因为是个轻量级…

从零开始用AI开发游戏(一)

1. 核心玩法设计 核心目标&#xff1a;玩家需在随机生成的3D迷宫中寻找出口&#xff0c;躲避陷阱、收集道具、解开谜题。核心机制&#xff1a; 随机生成迷宫&#xff1a;每次游戏生成不同结构的迷宫&#xff08;递归分割算法或深度优先搜索&#xff09;。第一人称视角&#xf…

AI-大模型中的流式输出与非流式输出

1.前言 在大模型API开发中&#xff0c;流式与非流式输出对应着两种不同的数据交互&#xff0c;在代码中stream中通过参数true与false来进行设定。 2.流式输出与非流式输出的原理 2.1.非流式输出-请求一次响应返回完整数据 非流式输出&#xff0c;传统的请求-响应模式&#xf…

【HarmonyOS Next】鸿蒙加固方案调研和分析

【HarmonyOS Next】鸿蒙加固方案调研和分析 一、前言 根据鸿蒙应用的上架流程&#xff0c;本地构建app文件后&#xff0c;上架到AGC平台&#xff0c;平台会进行解析。根据鸿蒙系统的特殊设置&#xff0c;仿照IOS的生态闭环方案。只能从AGC应用市场下载app进行安装。这样的流程…

蓝桥杯javaB组备战第二天 题目 区间次方和 编号3382

这是一个前缀和问题&#xff0c;但是不同于以为前缀和问题 前缀和问题求解思路&#xff1a; 创建一个前缀数组 s[] ,存储输入的元素的a[1]到a[n]的和 及&#xff1a;s[1] s[i-1]a[i] ,i>1 这样比暴力算法的复杂度要低很多可以将 时间复杂度从O(q*n*m)下降到 O(n*mq) …

《Android 平台架构系统启动流程详解》

目录 一、平台架构模块 1.1 Linux 内核 1.2 硬件抽象层 (HAL) 1.3 Android 运行时 1.4 原生 C/C 库 1.5 Java API 框架 1.6 系统应用 二、系统启动流程 2.1 Bootloader阶段 2.2 内核启动 2.3 Init进程&#xff08;PID 1&#xff09; 2.4 Zygote与System Serv…

强化学习(赵世钰版)-学习笔记(3.最优策略与贝尔曼最优方程)

这是本章在课程中的位置&#xff0c;属于基础工具中的最后一章&#xff0c;主要讨论了最优状态值&#xff08;Optimal State Value&#xff09;与最优策略&#xff08;Optimal Policy&#xff09;&#xff0c;并介绍了对应的计算方法-贝尔曼最优方程&#xff08;Bellman Optima…