ffmpeg ffplay.c 源码分析二:数据读取线程

本章主要是分析 数据读取线程read_thread 中的工作。如上图红色框框的部分

从ffplay框架分析我们可以看到,ffplay有专⻔的线程read_thread()读取数据,
且在调⽤av_read_frame 读取数据包之前需要做:
1.例如打开⽂件,
2.查找配置解码器,
3.初始化⾳视频输出等准备阶段,
主要包括三⼤步骤:
  • 准备⼯作
  • For循环读取数据
  • 退出线程处理

一 准备⼯作

准备⼯作主要包括以下步骤:
1. avformat_alloc_context 创建上下⽂
2. ic -> interrupt_callback . callback = decode_interrupt_cb;
3. avformat_open_input打开媒体⽂件
4. avformat_find_stream_info 读取媒体⽂件的包获取更多的stream信息
5. 检测是否指定播放起始时间,如果指定时间则seek到指定位置 avformat_seek_file
6. 查找 查找AVStream,讲对应的index值记录到 st_index [ AVMEDIA_TYPE_NB ];
        a. 根据⽤户指定来查找流 avformat_match_stream_specifier
        b. 使⽤av_find_best_stream查找流
7. 通过 AVCodecParameters和 av_guess_sample_aspect_ratio 计算出显示窗⼝的宽、⾼
8. stream_component_open打开⾳频、视频、字幕解码器,并创建相应的解码线程以及进⾏对应输出参数的初始化。

1. avformat_alloc_context 创建上下⽂

调⽤ avformat_alloc_context创建解复⽤器上下⽂
// 1. 创建上下⽂结构体,这个结构体是最上层的结构体,表示输⼊上下⽂
ic = avformat_alloc_context();

最终该ic 赋值给VideoState的ic变量
is->ic = ic; // videoState的ic指向分配的ic

2 ic->interrupt_callback

ic 这里是AVFormatContext ,

    /* 2.设置中断回调函数,如果出错或者退出,就根据目前程序设置的状态选择继续check或者直接退出 *//* 当open出现阻塞的时候时候,会调用interrupt_callback.callback* 回调函数中返回1则代表ffmpeg结束阻塞可以将操纵权交给用户线程并返回错误码* 回调函数中返回0则代表ffmpeg继续阻塞直到ffmpeg正常工作为止,所以要退出死等则需要返回1*/ic->interrupt_callback.callback = decode_interrupt_cb;ic->interrupt_callback.opaque = is;
那么这个  interrupt_callback 是个啥?
interrupt_callback⽤于ffmpeg内部在执⾏耗时操作时检查调⽤者是否有退出请求,避免⽤户退出请求没 有及时响应。
在什么时候触发这个 callback 呢?
avformat_open_input的触发
avformat_find_stream_info的触发
av_read_frame的触发

3.avformat_open_input()打开媒体⽂件

avformat_open_input⽤于打开输⼊⽂件(对于RTMP/RTSP/HTTP⽹络流也是⼀样,在ffmpeg内部都 抽象为URLProtocol,这⾥描述为⽂件是为了⽅便与后续提到的AVStream的流作区分),读取视频⽂件 的基本信息。

需要提到的两个参数是fmt和options。通过fmt可以强制指定视频⽂件的封装,options可以传递额外参数 给封装(AVInputFormat)。
主要代码:
    //特定选项处理if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);scan_all_pmts_set = 1;}/* 3.打开文件,主要是探测协议类型,如果是网络文件则创建网络链接等 */err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);

scan_all_pmts是mpegts的⼀个选项,表示扫描全部的ts流的"Program Map Table"表。这⾥在没有设定 该选项的时候,强制设为1。最后执⾏avformat_open_input。
参数的设置最终都是设置到对应的解复⽤器,⽐如:

二 For循环读取数据

三 退出线程处理

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

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

相关文章

Servlet 3.0的新特征

版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhlServlet 3.0概述 Servlet 3.0规范是在2009年随着Java EE 6的发布而推出的。它引入了一系列新特性和改进,旨在简化Web应用的开发和部署过程,并提高Web应用的性能和可扩展性。Servlet 3.0的发布标…

大语言模型-对比学习-Contrastive Learning

一、对比学习概念 对比学习是一种特殊的无监督学习方法。 旨在通过拉近相关样本的距离并且推远不相关样本的距离,来学习数据表示。 通常使用一种高自由度、自定义的规则来生成正负样本。在模型预训练中有着广泛的应用。 二、对比学习小案例 对比学习主要分为三个…

02 MySQL数据库管理

目录 1.数据库的结构 sql语言主要由以下几部分组成 2. 数据库与表的创建和管理 1,创建数据库 2,创建表并添加数据 3,添加一条数据 4,查询数据 5,更新数据 6,删除数据 3.用户权限管理 1.创建用户 …

js轮播图制作

实现一个简单的JavaScript轮播图可以通过以下步骤完成: 创建HTML结构,包括轮播图容器和图片列表。 使用CSS进行样式设置,包括隐藏多余的图片。 使用JavaScript编写函数来控制图片的切换。

C#中栈和堆以及修饰符

关于堆中字符串的存放 string s1"123" string s2"123" string s1"456" 此时s1输出为456 而s2仍然为123 因为在使用 String str "字符串" 的方式来创建String变量的时候,那么String的值便会存储在String常量池中&#x…

Keepalived和Haproxy

Keepalived和Haproxy 一、Keepalived 1、keepalived概念 调度器的高可用 vip地址主备之间的切换,主在工作时,vip地址值在主上,主停止工作,vip飘移到备服务器 在主备的优先级不变的情况下,主恢复工作,v…

C++——编译报重复定义错误的解决办法

原因: 头文件被多次编译。 解决办法: 找到包含头文件的地方,仔细检查。 比如: 这两句话是包含关系,写了第一句就不用第二句了。 因为:第一句是编译 tracker/detector/rknn_model_zoo/examples/yolov5/c…

【MySQL进阶之路 | 高级篇】简谈redo日志

1. 前言 事务有四种特性:原子性,一致性,隔离性和持久性。那么事务的四种特性到底是基于什么机制实现呢? 事务的隔离性由锁机制实现。而事务的原子性,一致性和持久性由事务的redo日志和undo日志来保证。 REDO LOG称为…

云计算实训13——DNS域名解析、ntp时间服务器配置、主从DNS配置、多区域DNS搭建

一、DNS域名解析 1.正向解析 将域名解析为IP地址 DNS正向解析核心配置 (1)安装bind [rootdns ~]# yum -y install bind (2)编辑配置文件 编辑named.conf文件,限定访问权限 [rootdns ~]# vim /etc/named.conf 编辑named.rfc文件,指定要访问的域名 [ro…

【数据结构】:用Java实现链表

在 ArrayList 任意位置插入或者删除元素时,就需要将后序元素整体往前或者往后搬移,时间复杂度为 O(n),效率比较低,因此 ArrayList 不适合做任意位置插入和删除比较多的场景。因此:java 集合中又引入了 LinkedList&…

一步一步测试DNS隧道

目录 0、前言 1、DNS解析 1.1 DNS简介 1.2 DNS查询类型 1.3 DNS解析过程 2、DNS隧道准备工作 2.1 DNS隧道介绍 2.1.1 什么是DNS隧道? 2.1.2 DNS隧道的原理 2.2 客户端、服务端准备 2.3 域名准备 2.4 连接隧道 2.5 遇坑 3、隧道确认和利用…

Windows本地启动Redis

找到本地redis目录 输入cmd,然后输入redis-server.exe redis.windows.conf,默认端口为6379 再新打开一个cmd,输入redis-cli.exe -p 6379 -a (你在redis.windows.conf中设置的密码)

如何做好服务器的安全管理

以下是一些服务器安全防护措施: 1、安装杀毒软件:安装杀毒软件是保护服务器免受病毒和恶意软件攻击的基本措施之一。保持杀毒软件更新至最新版本,定期扫描检测服务器以确保其不被病毒、蠕虫等恶意软件入侵。保护服务器免受侵害。像360杀毒&am…

HarmonyOS NEXT星河版零基础入门到实战

文章目录 一、HarmonyOS NEXT介绍学习内容1、鸿蒙APP开发2、能力套件开发3、全场景开发适合人群 持续更新中✒️总结 一、HarmonyOS NEXT介绍 放弃安卓框架之后,HarmonyOS NEXT成为真正独立于安卓、iOS的操作系统,堪称是一场史无前例的脱胎换骨。在其众多…

服务器利用宝塔面板部署Django项目

目录 1. 使用命令启动Django项目1.1 使用 Xshell 连接服务器1.2 安装Anaconda1.3 启动Django项目1.4 使用tmux实现项目的后台运行 2. 使用Python项目管理器部署项目2.1 安装宝塔面板和软件2.2 添加站点2.3 上传项目文件2.3.1 收集静态文件2.3.2 生成依赖文件 2.4 安装安装Pytho…

【周记】2024暑期集训第二周(未完待续)

文章目录 日常刷题记录合并果子题目解析算法思路代码实现 中位数题目解析算法思路代码实现 C学习笔记队列queue双端队列 deque优先队列 priority_queue定义常见操作 upper_bound 日常刷题记录 合并果子 题目解析 有一堆果子,每次可以将两小堆合并,耗费…

人的心体本乐,回归自己,清静快乐

94天 孔颜之乐,乐是心的本体;真乐,常人所共有; 人心本体,原来就没有什么不快乐的 - 陆元静问:孔颜之乐与七情之中的“ 乐 ”是否相同呢?我经常愁闷,未曾体会过“真乐”的感受&#x…

classfinal太强了,再也不怕被反编译了

这段时间在辛辛苦苦的编写一个算法程序,担心部署到客户服务器,客户反编译jar包,破解程序,那努力就白费了! 在网上查询,发现个好东东,classfinal可以加密jar包,防止反编译&#xff0…

华杉研发九学习日记18 集合 泛型

华杉研发九学习日记18 一,集合框架 1.1 集合和数组的区别 集合就是在java中用来保存多个对象的容器 集合是数组的升级版,集合中只能放置对象[object]. 数组: 在java中用来保存多个具有相同数据类型数据的容器 数组弊端: 1.数组只能保存…

【计算机网络】网络层——IPv4地址(个人笔记)

学习日期:2024.7.24 内容摘要:IPv4地址,分类编址,子网,无分类编址 IPv4地址概述 在TCP/IP体系中,IP地址是一个最基本的概念,IPv4地址就是给因特网上的每一台主机的每一个接口分配一个在全世界…