FFMPEG结构体分析:AVIOContext
注:写了一系列的结构体的分析的文章,在这里列一个列表:
FFMPEG结构体分析:AVStream
FFMPEG结构体分析:AVPacket
FFMPEG有几个最重要的结构体,包含了解协议,解封装,解码操作,此前已经进行过分析:
在此不再详述,其中AVIOContext是FFMPEG管理输入输出数据的结构体。本文将会详细分析一下该结构体里每个变量的含义和作用。
首先看一下结构体的定义(位于avio.h):
/* 雷霄骅 * 中国传媒大学/数字电视技术 * leixiaohua1020@126.com * */ /** * 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 { /** * 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. */ AVClass *av_class; 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 than buffer+buffer_size if the read function returned less data than requested, e.g. for streams where no 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 must_flush; /**< true if the next seek should flush */ int eof_reached; /**< true if eof reached */ 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; } AVIOContext;
AVIOContext中有以下几个变量比较重要:
unsigned char *buffer:缓存开始位置
int buffer_size:缓存大小(默认32768)
unsigned char *buf_ptr:当前指针读取到的位置
unsigned char *buf_end:缓存结束的位置
void *opaque:URLContext结构体
在解码的情况下,buffer用于存储ffmpeg读入的数据。例如打开一个视频文件的时候,先把数据从硬盘读入buffer,然后在送给解码器用于解码。
其中opaque指向了URLContext。注意,这个结构体并不在FFMPEG提供的头文件中,而是在FFMPEG的源代码中。从FFMPEG源代码中翻出的定义如下所示:
typedef struct URLContext { const AVClass *av_class; ///< information for av_log(). Set by url_open(). struct URLProtocol *prot; int flags; int is_streamed; /**< true if streamed (no seek possible), default = false */ int max_packet_size; /**< if non zero, the stream is packetized with this max packet size */ void *priv_data; char *filename; /**< specified URL */ int is_connected; AVIOInterruptCB interrupt_callback; } URLContext;
URLContext结构体中还有一个结构体URLProtocol。注:每种协议(rtp,rtmp,file等)对应一个URLProtocol。这个结构体也不在FFMPEG提供的头文件中。从FFMPEG源代码中翻出其的定义:
typedef struct URLProtocol { const char *name; int (*url_open)(URLContext *h, const char *url, int flags); int (*url_read)(URLContext *h, unsigned char *buf, int size); int (*url_write)(URLContext *h, const unsigned char *buf, int size); int64_t (*url_seek)(URLContext *h, int64_t pos, int whence); int (*url_close)(URLContext *h); struct URLProtocol *next; int (*url_read_pause)(URLContext *h, int pause); int64_t (*url_read_seek)(URLContext *h, int stream_index, int64_t timestamp, int flags); int (*url_get_file_handle)(URLContext *h); int priv_data_size; const AVClass *priv_data_class; int flags; int (*url_check)(URLContext *h, int mask); } URLProtocol;
在这个结构体中,除了一些回调函数接口之外,有一个变量const char *name,该变量存储了协议的名称。每一种输入协议都对应这样一个结构体。
URLProtocol ff_file_protocol = { .name = "file", .url_open = file_open, .url_read = file_read, .url_write = file_write, .url_seek = file_seek, .url_close = file_close, .url_get_file_handle = file_get_handle, .url_check = file_check, };
URLProtocol ff_rtmp_protocol = { .name = "rtmp", .url_open = rtmp_open, .url_read = rtmp_read, .url_write = rtmp_write, .url_close = rtmp_close, .url_read_pause = rtmp_read_pause, .url_read_seek = rtmp_read_seek, .url_get_file_handle = rtmp_get_file_handle, .priv_data_size = sizeof(RTMP), .flags = URL_PROTOCOL_FLAG_NETWORK, };
URLProtocol ff_udp_protocol = { .name = "udp", .url_open = udp_open, .url_read = udp_read, .url_write = udp_write, .url_close = udp_close, .url_get_file_handle = udp_get_file_handle, .priv_data_size = sizeof(UDPContext), .flags = URL_PROTOCOL_FLAG_NETWORK, };
等号右边的函数是完成具体读写功能的函数。可以看一下file协议的几个函数(其实就是读文件,写文件这样的操作)(file.c):
/* *雷霄骅 *leixiaohua1020@126.com *中国传媒大学/数字电视技术 */ /* standard file protocol */ static int file_read(URLContext *h, unsigned char *buf, int size) { int fd = (intptr_t) h->priv_data; int r = read(fd, buf, size); return (-1 == r)?AVERROR(errno):r; } static int file_write(URLContext *h, const unsigned char *buf, int size) { int fd = (intptr_t) h->priv_data; int r = write(fd, buf, size); return (-1 == r)?AVERROR(errno):r; } static int file_get_handle(URLContext *h) { return (intptr_t) h->priv_data; } static int file_check(URLContext *h, int mask) { struct stat st; int ret = stat(h->filename, &st); if (ret < 0) return AVERROR(errno); ret |= st.st_mode&S_IRUSR ? mask&AVIO_FLAG_READ : 0; ret |= st.st_mode&S_IWUSR ? mask&AVIO_FLAG_WRITE : 0; return ret; } #if CONFIG_FILE_PROTOCOL static int file_open(URLContext *h, const char *filename, int flags) { int access; int fd; av_strstart(filename, "file:", &filename); if (flags & AVIO_FLAG_WRITE && flags & AVIO_FLAG_READ) { access = O_CREAT | O_TRUNC | O_RDWR; } else if (flags & AVIO_FLAG_WRITE) { access = O_CREAT | O_TRUNC | O_WRONLY; } else { access = O_RDONLY; } #ifdef O_BINARY access |= O_BINARY; #endif fd = open(filename, access, 0666); if (fd == -1) return AVERROR(errno); h->priv_data = (void *) (intptr_t) fd; return 0; } /* XXX: use llseek */ static int64_t file_seek(URLContext *h, int64_t pos, int whence) { int fd = (intptr_t) h->priv_data; if (whence == AVSEEK_SIZE) { struct stat st; int ret = fstat(fd, &st); return ret < 0 ? AVERROR(errno) : st.st_size; } return lseek(fd, pos, whence); } static int file_close(URLContext *h) { int fd = (intptr_t) h->priv_data; return close(fd); }
FFMPEG结构体分析:AVIOContext的更多相关文章
- FFMPEG结构体分析:AVPacket
注:写了一系列的结构体的分析的文章,在这里列一个列表: FFMPEG结构体分析:AVFrame FFMPEG结构体分析:AVFormatContext FFMPEG结构体分析:AVCodecConte ...
- FFMPEG结构体分析:AVStream
注:写了一系列的结构体的分析的文章,在这里列一个列表: FFMPEG结构体分析:AVFrame FFMPEG结构体分析:AVFormatContext FFMPEG结构体分析:AVCodecConte ...
- FFMPEG结构体分析:AVCodec
注:写了一系列的结构体的分析的文章,在这里列一个列表: FFMPEG结构体分析:AVFrame FFMPEG结构体分析:AVFormatContext FFMPEG结构体分析:AVCodecConte ...
- FFMPEG结构体分析:AVCodecContext
注:写了一系列的结构体的分析的文章,在这里列一个列表: FFMPEG结构体分析:AVFrame FFMPEG结构体分析:AVFormatContext FFMPEG结构体分析:AVCodecConte ...
- FFMPEG结构体分析:AVFormatContext
注:写了一系列的结构体的分析的文章,在这里列一个列表: FFMPEG结构体分析:AVFrameFFMPEG结构体分析:AVFormatContextFFMPEG结构体分析:AVCodecContext ...
- FFMPEG结构体分析:AVFrame
注:写了一系列的结构体的分析的文章,在这里列一个列表: FFMPEG结构体分析:AVFrameFFMPEG结构体分析:AVFormatContextFFMPEG结构体分析:AVCodecContext ...
- FFMPEG结构体分析:AVCodecContext(转)
注:写了一系列的结构体的分析的文章,在这里列一个列表: FFMPEG结构体分析:AVFrameFFMPEG结构体分析:AVFormatContextFFMPEG结构体分析:AVCodecContext ...
- [转载] FFMPEG结构体分析:AVFrame
注:写了一系列的结构体的分析的文章,在这里列一个列表: FFMPEG结构体分析:AVFrameFFMPEG结构体分析:AVFormatContextFFMPEG结构体分析:AVCodecContext ...
- FFMPEG结构体分析:AVFrame(解码后的数据)
https://blog.csdn.net/jxcr1984/article/details/52766524 本文转自: http://blog.csdn.net/leixiaohua1020/ar ...
随机推荐
- 在java程序中实现发送邮件的功能
最近比较忙,在做一个人事管理系统的项目,在这项目需求中,需要一个发送邮件的功能.这个时候我们可以使用javamail的jar包来实现完美需要的功能,在这里简单的分享一个最基础的发邮件功能. 首先我们需 ...
- 解决linux删除文件后空间没有释放问题
linux删除文件后沒有释放空间 今天发现一台服务器的home空间满了,于是要清空没用的文件,当我删除文件后,发现可用空间沒有变化 os:centos4.7 现象: 发现当前磁盘空间使用情况: [ro ...
- 本人正竞选CSDN博客之星,欢迎各位来访的朋友能为我投上一票
投票网址:http://blog.csdn.net/vote/candidate.html?username=morixinguan&from=timeline 谢谢各位!
- 关于JQuery中的ajax请求或者post请求的回调方法中的操作执行或者变量修改没反映的问题
前段时间做一个项目,而项目中所有的请求都要用jquery 中的ajax请求或者post请求,但是开始处理一些简单操作还好,但是自己写了一些验证就出现问题了,比如表单提交的时候,要验证帐号的唯一性,所以 ...
- Android自定义View(二、深入解析自定义属性)
转载请标明出处: http://blog.csdn.net/xmxkf/article/details/51468648 本文出自:[openXu的博客] 目录: 为什么要自定义属性 怎样自定义属性 ...
- SQLite Where 子句(http://www.w3cschool.cc/sqlite/sqlite-where-clause.html)
SQLite Where 子句 SQLite的 WHERE 子句用于指定从一个表或多个表中获取数据的条件. 如果满足给定的条件,即为真(true)时,则从表中返回特定的值.您可以使用 WHERE 子句 ...
- Android开发艺术探索笔记——第一章:Activity的生命周期和启动模式
Android开发艺术探索笔记--第一章:Activity的生命周期和启动模式 怀着无比崇敬的心情翻开了这本书,路漫漫其修远兮,程序人生,为自己加油! 一.序 作为这本书的第一章,主席还是把Activ ...
- Effective C++ ——模板和泛型编程
条款41:了解隐式接口和编译器多态 以public继承的类,
- Android初级教程:使用xml序列器
之前备份短信的时候生成xml都是手动拼写的,有一个问题:当短信里面存在</body>这样的标签的时候,最后结果就不是完整的xml文件,显然出错.但是,今天使用序列化器的方式,就能有效的解决 ...
- Android多点触摸缩放图片-android学习之旅(四)
获取多触摸点 核心代码: 获取触摸点的个数和位置 public boolean onTouch(View v, MotionEvent event) { switch (event.getAction ...