当前位置: 首页 > java >正文

AVIOContext 再学习

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

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.xdnf.cn/news/3626.html

相关文章:

  • Spring 容器相关的核心注解​
  • 19. LangChain安全与伦理:如何避免模型“幻觉“与数据泄露?
  • Linux电源管理(5)_Hibernate和Sleep功能介绍
  • ElasticSearch深入解析(九):Object、Nested、Flattened类型
  • 【RabbitMQ】 RabbitMQ快速上手
  • Python 函数装饰器和闭包(使用装饰器改进“策略”模式)
  • 玩转Docker | 使用Docker部署AI证件照工具
  • 【2025】ORM框架是什么?有哪些常用?Mybatis和Hibernate是什么样的?
  • ES6/ES11知识点
  • wpf CommandParameter 传递MouseWheelEventArgs参数 ,用 MvvmLight 实现
  • Word域操作记录(从1开始的毕业论文格式排版)
  • 神经网络的基本概念与深度解析——基于生物机制的仿生建模与工程实现
  • Spring Boot的GraalVM支持:构建低资源消耗微服务
  • Kubernetes(k8s)学习笔记(四)--入门基本操作
  • 双指针(5)——有效三角形个数
  • 杭电oj(1180、1181)题解
  • “淘宝闪购”提前4天全量,意味着什么?
  • 传奇各职业/战士/法师/道士/手套/手镯/护腕/神秘腰带爆率及出处产出地/圣战/法神/天尊/祈祷/虹魔/魔血
  • Demo02_基于寄存器+标准库开发的项目
  • 传奇各职业/战士/法师/道士/戒指爆率及出处产出地/圣战/法神/天尊/虹魔/魔血/麻痹/超负载/求婚/隐身/传送/复活/护身/祈祷/火焰
  • Linux系统常用命令、标准C库函数和系统调用
  • new和malloc的区别
  • 一场陟遐自迩的 SwiftUI + CoreData 性能优化之旅(上)
  • Redis总结及设置营业状态案例
  • 泰迪杯特等奖案例学习资料:基于CLIP模型微调与知识蒸馏的多模态图文检索系统设计
  • B站Michale_ee——ESP32_IDF SDK——FreeRTOS_7 流数据缓冲区、消息缓冲区
  • Python基于深度学习的网络舆情分析系统(附源码,部署)
  • 基于蒙特卡洛模拟的电路容差分析与设计优化
  • 倒排索引与数据库索引
  • 拆解一个550-800Mhz的LC滤波器内部大图配测试曲线