这个目前阶段用的不多,暂时不要花费太多精力。

url 的格式不同,使用的传输层协议也不同。这块看代码还没看到自己想的这样。

目前看的信息是:avformatContext 的 io_open 回调函数 在默认情况下叫 io_open_default,在解复用的 avformat_open_input 方法中一定会调用。那么我们如果不使用这个默认的 io_open_default,使用自己写的回调函数,会怎么样呢? 

还看到的信息:avformatContext的pb (    AVIOContext *pb;)是通过 avio_alloc_context方法创建的,那么我们如果自己创建,也可以使用avio_alloc_context创建。

AVIOContext *avio_alloc_context(unsigned char *buffer,int buffer_size,int write_flag,void *opaque,int (*read_packet)(void *opaque, uint8_t *buf, int buf_size),int (*write_packet)(void *opaque, uint8_t *buf, int buf_size),int64_t (*seek)(void *opaque, int64_t offset, int whence))

调用AVFormatContext* avformatContext = nullptr;const char* url_400 = "./120/400_300_25.mp4";const char* url_1080 = "./120/1920_1080_25.mp4";int ret = avformat_open_input(&avformatContext, url_400, nullptr, nullptr);1. avformat_open_input 方法内部会重新创建 avformat_alloc_context,创建 AVFormatContext *s = avformat_alloc_context()  1.1 avformat_alloc_context内部调用 avformat_get_context_defaults
static void avformat_get_context_defaults(AVFormatContext *s)
{memset(s, 0, sizeof(AVFormatContext));s->av_class = &av_format_context_class;s->io_open  = io_open_default; //注意这里,设定了 AVFormatContext 的 io_open 回调函数s->io_close = io_close_default;av_opt_set_defaults(s);
}1.2 然后调用if ((ret = init_input(s, filename, &tmp)) < 0)------>		if ((ret = s->io_open(s, &s->pb, filename, AVIO_FLAG_READ | s->avio_flags, options)) < 0)------> 	也就是调用 io_open_default方法,传递参数为 AVFormatContext,AVFormatContext->pb的地址,后面在 ------->	调用 return ffio_open_whitelist(pb, url, flags, &s->interrupt_callback, options, s->protocol_whitelist, s->protocol_blacklist);---------> 和当前关系不大    err = ffurl_open_whitelist(&h, filename, flags, int_cb, options, whitelist, blacklist, NULL);--------->		 err = ffio_fdopen(s, h);int ffio_fdopen(AVIOContext **s, URLContext *h)------>			ffio_fdopen内部做了 avio_alloc_context,创建了AVIOContext *s,也就是 avformatContext的 pb,io_open --- A callback for opening new IO streams.从这里可以看出几点:
0. 当avformat_open_input方法中传递的 avformatContext是nullptr,  则:AVFormatContext->io_open = io_open_default
1.即使我们使用 AVFormatContext *avformat_alloc_context(void)创建了avfromatContext,内部也会   AVFormatContext->io_open = io_open_default
1. io_open 回调函数,在avformat_open_input方法中会调用,也就是说,默认会调用 io_open_default 函数
2. 那么我们可以自己定义 AVFormatContext->io_open的回调函数吗?那要看 io_open_default  函数的功能是啥?

avio_alloc_context 函数说明

AVIOContext *avio_alloc_context(unsigned char *buffer,int buffer_size,int write_flag,void *opaque,int (*read_packet)(void *opaque, uint8_t *buf, int buf_size),int (*write_packet)(void *opaque, uint8_t *buf, int buf_size),int64_t (*seek)(void *opaque, int64_t offset, int whence));opaque是 read_packet / write_packet 的第⼀个参数,指向⽤户数据。
buffer和buffer_size是 read_packet / write_packet 的第⼆个和第三个参数,是供FFmpeg使⽤
的数据区。
buffer ⽤作FFmpeg输⼊时,由⽤户负责向 buffer 中填充数据,FFmpeg取⾛数据。
buffer ⽤作FFmpeg输出时,由FFmpeg负责向 buffer 中填充数据,⽤户取⾛数据。
write_flag是缓冲区读写标志,读写的主语是指FFmpeg。
write_flag 为1时, buffer ⽤于写,即作为FFmpeg输出。
write_flag 为0时, buffer ⽤于读,即作为FFmpeg输⼊。
read_packet和write_packet是函数指针,指向⽤户编写的回调函数。
seek也是函数指针,需要⽀持seek时使⽤。 可以类⽐fseek的机制

需要和如下的结合起来学习,

AVFormatContext 再分析零-CSDN博客

AVIOContext  是 avformatContext 结构体中一个成员变量

是传输层的

中文翻译:

*-demuxing:

要么由用户在avformat_open_input()之前设置(然后用户必须手动关闭它),

要么由avformat_opend_input()设置。这里应该想要表达的是如果不设置,那么avformat_opend_input方法内部会自动查找。


*-muxing:由用户在avformat_write_header()之前设置。调用者必须负责关闭/释放IO上下文。
*如果在中设置了AVFMT_NOFILE标志,则不要设置此字段iform/oform.flags。在这种情况下,(解)复用器将以其他方式处理I/O,此字段将为NULL。

    /*** I/O context.** - demuxing: either set by the user before avformat_open_input() (then*             the user must close it manually) or set by avformat_open_input().* - muxing: set by the user before avformat_write_header(). The caller must*           take care of closing / freeing the IO context.** Do NOT set this field if AVFMT_NOFILE flag is set in* iformat/oformat.flags. In such a case, the (de)muxer will handle* I/O in some other way and this field will be NULL.*/AVIOContext *pb;

AVIOContext 自己是一个结构体

/*** Bytestream IO Context.* New fields can be added to the end with minor version bumps.* Removal, reordering and changes to existing fields require a major* version bump.* sizeof(AVIOContext) must not be used outside libav*.** @note None of the function pointers in AVIOContext should be called*       directly, they should only be set by the client application*       when implementing custom I/O. Normally these are set to the*       function pointers specified in avio_alloc_context()*/
typedef struct AVIOContext {/*** A class for private options.** If this AVIOContext is created by avio_open2(), av_class is set and* passes the options down to protocols.** If this AVIOContext is manually allocated, then av_class may be set by* the caller.** warning -- this field can be NULL, be sure to not pass this AVIOContext* to any av_opt_* functions in that case.*/const AVClass *av_class;/** The following shows the relationship between buffer, buf_ptr,* buf_ptr_max, buf_end, buf_size, and pos, when reading and when writing* (since AVIOContext is used for both):************************************************************************************                                   READING************************************************************************************                            |              buffer_size              |*                            |---------------------------------------|*                            |                                       |**                         buffer          buf_ptr       buf_end*                            +---------------+-----------------------+*                            |/ / / / / / / /|/ / / / / / /|         |*  read buffer:              |/ / consumed / | to be read /|         |*                            |/ / / / / / / /|/ / / / / / /|         |*                            +---------------+-----------------------+**                                                         pos*              +-------------------------------------------+-----------------+*  input file: |                                           |                 |*              +-------------------------------------------+-----------------+*************************************************************************************                                   WRITING************************************************************************************                             |          buffer_size                 |*                             |--------------------------------------|*                             |                                      |**                                                buf_ptr_max*                          buffer                 (buf_ptr)       buf_end*                             +-----------------------+--------------+*                             |/ / / / / / / / / / / /|              |*  write buffer:              | / / to be flushed / / |              |*                             |/ / / / / / / / / / / /|              |*                             +-----------------------+--------------+*                               buf_ptr can be in this*                               due to a backward seek**                            pos*               +-------------+----------------------------------------------+*  output file: |             |                                              |*               +-------------+----------------------------------------------+**/unsigned char *buffer;  /**< Start of the buffer. */int buffer_size;        /**< Maximum buffer size */unsigned char *buf_ptr; /**< Current position in the buffer */unsigned char *buf_end; /**< End of the data, may be less thanbuffer+buffer_size if the read function returnedless data than requested, e.g. for streams whereno more data has been received yet. */void *opaque;           /**< A private pointer, passed to the read/write/seek/...functions. */int (*read_packet)(void *opaque, uint8_t *buf, int buf_size);int (*write_packet)(void *opaque, uint8_t *buf, int buf_size);int64_t (*seek)(void *opaque, int64_t offset, int whence);int64_t pos;            /**< position in the file of the current buffer */int eof_reached;        /**< true if was unable to read due to error or eof */int write_flag;         /**< true if open for writing */int max_packet_size;unsigned long checksum;unsigned char *checksum_ptr;unsigned long (*update_checksum)(unsigned long checksum, const uint8_t *buf, unsigned int size);int error;              /**< contains the error code or 0 if no error happened *//*** Pause or resume playback for network streaming protocols - e.g. MMS.*/int (*read_pause)(void *opaque, int pause);/*** Seek to a given timestamp in stream with the specified stream_index.* Needed for some network streaming protocols which don't support seeking* to byte position.*/int64_t (*read_seek)(void *opaque, int stream_index,int64_t timestamp, int flags);/*** A combination of AVIO_SEEKABLE_ flags or 0 when the stream is not seekable.*/int seekable;/*** max filesize, used to limit allocations* This field is internal to libavformat and access from outside is not allowed.*/int64_t maxsize;/*** avio_read and avio_write should if possible be satisfied directly* instead of going through a buffer, and avio_seek will always* call the underlying seek function directly.*/int direct;/*** Bytes read statistic* This field is internal to libavformat and access from outside is not allowed.*/int64_t bytes_read;/*** seek statistic* This field is internal to libavformat and access from outside is not allowed.*/int seek_count;/*** writeout statistic* This field is internal to libavformat and access from outside is not allowed.*/int writeout_count;/*** Original buffer size* used internally after probing and ensure seekback to reset the buffer size* This field is internal to libavformat and access from outside is not allowed.*/int orig_buffer_size;/*** Threshold to favor readahead over seek.* This is current internal only, do not use from outside.*/int short_seek_threshold;/*** ',' separated list of allowed protocols.*/const char *protocol_whitelist;/*** ',' separated list of disallowed protocols.*/const char *protocol_blacklist;/*** A callback that is used instead of write_packet.*/int (*write_data_type)(void *opaque, uint8_t *buf, int buf_size,enum AVIODataMarkerType type, int64_t time);/*** If set, don't call write_data_type separately for AVIO_DATA_MARKER_BOUNDARY_POINT,* but ignore them and treat them as AVIO_DATA_MARKER_UNKNOWN (to avoid needlessly* small chunks of data returned from the callback).*/int ignore_boundary_point;/*** Internal, not meant to be used from outside of AVIOContext.*/enum AVIODataMarkerType current_type;int64_t last_time;/*** A callback that is used instead of short_seek_threshold.* This is current internal only, do not use from outside.*/int (*short_seek_get)(void *opaque);int64_t written;/*** Maximum reached position before a backward seek in the write buffer,* used keeping track of already written data for a later flush.*/unsigned char *buf_ptr_max;/*** Try to buffer at least this amount of data before flushing it*/int min_packet_size;
} AVIOContext;

ffmpeg 是如何通过参数url 找到具体的 AVIOContext 的?

在解复用一个本地的mp4文件的时候,我们 是这样调用的,传递的 url的值是 "./120/400_300_25.mp4"

    const char* url_400 = "./120/400_300_25.mp4";

    int ret = avformat_open_input(&avformatContext, url_400, nullptr, nullptr);

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

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

相关文章

在Java项目中实现本地语音识别与热点检测,并集成阿里云智能语音服务

引言 随着语音交互技术的发展&#xff0c;如何高效地处理用户的语音输入成为许多应用的重要课题。本文将详细介绍如何在一个Java项目中同时实现&#xff1a; 基于Vosk的本地语音识别&#xff1a;无需调用云端API即可完成语音到文本的转换。本地热点语音内容识别&#xff1a;对…

第15章 对API的身份验证和授权

第15章 对API的身份验证和授权 在构建RESTful API时,确保只有经过身份验证和授权的用户才能访问特定资源是至关重要的。身份验证是确认用户身份的过程,而授权则是决定用户是否有权访问特定资源的过程。在本章中,我们将详细探讨如何在ASP.NET Core Web API中实现身份验证和授…

asp.net客户管理系统批量客户信息上传系统客户跟单系统crm

# crm-150708 客户管理系统批量客户信息上传系统客户跟单系统 # 开发背景 本软件是给郑州某企业管理咨询公司开发的客户管理系统软件 # 功能 1、导入客户数据到系统 2、批量将不同的客户分配给不同的业务员跟进 3、可以对客户数据根据紧急程度标记不同的颜色&#xff0c…

深入理解现代JavaScript:从ES6+语法到Fetch API

引言 JavaScript作为Web开发的基石语言&#xff0c;近年来经历了翻天覆地的变化。ES6(ECMAScript 2015)的发布带来了革命性的新特性&#xff0c;而现代浏览器提供的API也让前端开发变得更加强大和高效。本文将深入探讨ES6核心语法、DOM操作优化技巧以及使用Fetch API进行异步请…

仙盟创梦IDE-智能编程,C#判断数组中是否存在key

一、net4 net core版本 使用LINQ的Contains方法 string[] array { "apple", "banana", "cherry" };string key "banana";bool exists array.Contains(key);if (exists){Console.WriteLine($"数组中存在键 {key}");}else…

360驱动大师v2.0(含网卡版)驱动工具软件下载及安装教程

1.软件名称&#xff1a;360驱动大师 2.软件版本&#xff1a;2.0 3.软件大小&#xff1a;218 MB 4.安装环境&#xff1a;win7/win10/win11 5.下载地址&#xff1a; https://www.kdocs.cn/l/cdZMwizD2ZL1?RL1MvMTM%3D 提示&#xff1a;先转存后下载&#xff0c;防止资源丢失&…

2025年- H22-Lc130-206. 反转链表(链表)---java版

1.题目描述 2.思路 使用迭代法 (1)定义一个前指针 (2)然后定义两个变量 curr&#xff08;head&#xff09;&#xff0c;curr.next。 (3)curr和curr.next交换位置&#xff08;只要当前指针不为空&#xff0c;执行两两交换&#xff09; 3.代码实现 /*** Definition for singly-…

机器学习常用评价指标

1. 指标说明 (1) AccuracyClassification&#xff08;准确率&#xff09; • 计算方式&#xff1a;accuracy_score(y_true, y_pred) • 作用&#xff1a; 衡量模型正确预测的样本比例&#xff08;包括所有类别&#xff09;。 公式&#xff1a; Accuracy TP TN TP TN FP…

CGI(Common Gateway Interface)协议详解

CGI&#xff08;通用网关接口&#xff09;是一种标准化的协议&#xff0c;定义了 Web服务器 与 外部程序&#xff08;如脚本或可执行文件&#xff09;之间的数据交互方式。它允许服务器动态生成网页内容&#xff0c;而不仅仅是返回静态文件。 1. CGI 的核心作用 动态内容生成&a…

2025.4.29总结

工作&#xff1a;最近手头活变得多起来了&#xff0c;毕竟要测两个版本&#xff0c;有时候觉得很奇怪&#xff0c;活少的时候&#xff0c;又想让别人多分点活&#xff0c;活多的时候&#xff0c;又会有些许不自然。这种反差往往伴随着项目的节奏&#xff0c;伴随着两个极端。所…

【KWDB 创作者计划】技术解读:多模架构、高效时序数据处理与分布式实现

技术解读&#xff1a;多模架构、高效时序数据处理与分布式实现 一、多模架构1.1 架构概述1.2 源码分析1.3 实现流程 二、高效时序数据处理2.1 处理能力概述2.2 源码分析2.3 实现流程 三、分布式实现3.1 分布式特性概述3.2 源码分析3.3 实现流程 四、总结 在当今数据爆炸的时代&…

# 前后端分离象棋对战项目开发记录

1. **结构清晰**&#xff1a;使用更直观的标题、分段和列表&#xff0c;增强可读性。 2. **视觉美观**&#xff1a;添加Markdown格式化&#xff08;如代码块、加粗、斜体&#xff09;&#xff0c;并建议配色和排版风格。 3. **内容精炼**&#xff1a;精简冗余表述&#xff0c;突…

HarmonyOS NEXT 诗词元服务项目开发上架全流程实战(一、项目介绍及实现效果)

在当今数字化时代&#xff0c;如何让传统文化与现代科技相结合&#xff0c;成为了一个值得思考的问题。诗词作为中国传统文化的重要组成部分&#xff0c;承载着丰富的历史信息和文化内涵。为了让更多人了解和欣赏诗词的魅力&#xff0c;我们决定开发一款基于HarmonyOS NEXT的诗…

linux jounery 日志相关问题

/var/log 目录 是 Linux 系统中存放各种日志文件的标准位置。 这些日志文件记录了系统及其服务的运行状态。 日志文件来源 系统日志 由 syslog 或 systemd-journald&#xff08;如果使用 systemd 的话&#xff09;等日志服务生成。记录内核消息和各种系统事件&#xff0c;例如…

JavaWeb学习打卡-Day7-正向代理、反向代理、Nginx

正向代理 概念&#xff1a;正向代理是一个位于客户端和目标服务器之间的代理服务器&#xff08;中间服务器&#xff09;。为了从目标服务器取得内容&#xff0c;客户端向代理服务器发送一个请求&#xff0c;并且指定目标服务器&#xff0c;之后代理向目标服务器转发请求&#…

AI算法可视化:如何用Matplotlib与Seaborn解释模型?

AI算法可视化&#xff1a;如何用Matplotlib与Seaborn解释模型&#xff1f; 系统化学习人工智能网站&#xff08;收藏&#xff09;&#xff1a;https://www.captainbed.cn/flu 文章目录 AI算法可视化&#xff1a;如何用Matplotlib与Seaborn解释模型&#xff1f;摘要引言基础可…

GoogleTest:TEST_F

GoogleTest:简单示例及ASSERT/EXPECT说明-CSDN博客 介绍了写一个简单的测试用例 如果某些测试用例在开始测试前需要先做一些准备工作,那么如果每次都需要先准备,那么会比较的麻烦,基于这种情况可以使用GoogleTest的TEST_F方法。 简单点说,就是需要先定义一个继承于testin…

【云备份】配置文件加载模块

目录 一.为什么要配置文件 二.配置文件的实现 三.单例文件配置类设计 四.源码 一.为什么要配置文件 我们将服务端程序运行中用到的一些关键信息保存到配置文件中&#xff0c;这样可以使程序的运行更加灵活。 这样做的好处是&#xff0c;未来如果我们想要修改一些关键信息&…

文号验证-同时对两个输入框验证

文号验证-同时对两个输入框验证 效果&#xff1a; 一、如果有多个文号&#xff1a; <div v-for"(item, index) in approvalForm.productApprovalTypeEvents" :key"index"> <el-form-itemlabel"文号":prop"productApprovalTypeEv…

高翔视觉slam中常见的OpenCV和Eigen的几种数据类型的内存布局及分配方式详解

vector<Eigen::Vector2d, Eigen::aligned_allocator<Eigen::Vector2d>> 内存布局及分配方式详解 1. 内存对齐的必要性 Eigen 的固定大小类型(如 Eigen::Vector2d、Eigen::Matrix4d 等)需要 16 字节内存对齐,以支持 SIMD 指令(如 SSE/AVX)的并行计算。若未对…