注:写了一系列的结构体的分析的文章,在这里列一个列表:

FFMPEG结构体分析:AVFrame
FFMPEG结构体分析:AVFormatContext
FFMPEG结构体分析:AVCodecContext
FFMPEG结构体分析:AVIOContext
FFMPEG结构体分析:AVCodec
FFMPEG结构体分析:AVStream
FFMPEG结构体分析:AVPacket

FFMPEG有几个最重要的结构体,包含了解协议,解封装,解码操作,此前已经进行过分析:

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 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 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,该变量存储了协议的名称。每一种输入协议都对应这样一个结构体。

比如说,文件协议中代码如下(file.c):
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,
};
libRTMP中代码如下(libRTMP.c):
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,
};
udp协议代码如下(udp.c):

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_PROTOCOLstatic 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_BINARYaccess |= O_BINARY;
#endiffd = 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相关推荐

  1. FFMPEG结构体分析:AVCodecContext(转)

    注:写了一系列的结构体的分析的文章,在这里列一个列表: FFMPEG结构体分析:AVFrame FFMPEG结构体分析:AVFormatContext FFMPEG结构体分析:AVCodecConte ...

  2. FFMPEG结构体分析:AVPacket

    注:写了一系列的结构体的分析的文章,在这里列一个列表: FFMPEG结构体分析:AVFrame FFMPEG结构体分析:AVFormatContext FFMPEG结构体分析:AVCodecConte ...

  3. FFMPEG结构体分析:AVStream

    注:写了一系列的结构体的分析的文章,在这里列一个列表: FFMPEG结构体分析:AVFrame FFMPEG结构体分析:AVFormatContext FFMPEG结构体分析:AVCodecConte ...

  4. FFMPEG结构体分析:AVCodec

    注:写了一系列的结构体的分析的文章,在这里列一个列表: FFMPEG结构体分析:AVFrame FFMPEG结构体分析:AVFormatContext FFMPEG结构体分析:AVCodecConte ...

  5. FFMPEG结构体分析:AVCodecContext

    注:写了一系列的结构体的分析的文章,在这里列一个列表: FFMPEG结构体分析:AVFrame FFMPEG结构体分析:AVFormatContext FFMPEG结构体分析:AVCodecConte ...

  6. FFMPEG结构体分析:AVFormatContext

    注:写了一系列的结构体的分析的文章,在这里列一个列表: FFMPEG结构体分析:AVFrame FFMPEG结构体分析:AVFormatContext FFMPEG结构体分析:AVCodecConte ...

  7. FFMPEG结构体分析:AVFrame

    注:写了一系列的结构体的分析的文章,在这里列一个列表: FFMPEG结构体分析:AVFrame FFMPEG结构体分析:AVFormatContext FFMPEG结构体分析:AVCodecConte ...

  8. FFMPEG结构体分析

    文章列表: FFMPEG结构体分析之AVCodecContext FFMPEG结构体分析之AVPacket FFMPEG结构体分析之AVCodec FFMPEG结构体分析之AVStream FFMPE ...

  9. ffmpeg 结构体分析

    AVFrame AVFrame结构体一般用于存储原始数据(即非压缩数据,例如对视频来说是YUV,RGB,对音频来说是PCM),此外还包含了一些相关的信息.比如说,解码的时候存储了宏块类型表,QP表,运 ...

最新文章

  1. iOS开发之使用CocoaPods更新第三方出现“target overrides the `OTHER_LDFLAGS`……”问题解决方案
  2. Xtrabackup备份、还原、恢复Mysql操作大全
  3. rpm包安装mysql5.6
  4. 【对讲机的那点事】玩无线电,你知道的天线有多少种?
  5. 编写一个方法,找出两个数字中最大的那一个。不得使用if-else或其他比较运算符。...
  6. mysql union all 别名_MySQL Union合并查询数据及表别名、字段别名用法分析
  7. python类型-Python基本内置数据类型有哪些?
  8. 【沟通的艺术】故事大王
  9. C#——委托(delegate)DEMO
  10. 通过btrace排查线上频繁Full GC的case 1
  11. C#中宏定义#define、预处理#if #else #endif的使用
  12. python剪切文件如何恢复_用python实现的可以拷贝或剪切一个文件列表中的所有文件...
  13. Presto?还是 Hive? 你们知道大数据查询性能谁更强吗?
  14. arcgis已试图对空几何执行该操作_ArcGIS中坐标转换和投影变换
  15. pyspark分类算法之多层感知机神经网络分类器模型实践【MLPClassifier】
  16. 人工智能 AI技术学习路线图 初阶+中阶+高阶
  17. 数据库的开窗函数学习
  18. 十大经典排序算法总结 (Python)
  19. Uva 12563 - Jin Ge Jin Qu(01背包)
  20. 大学生个人网站作业 超简单DIV CSS个人网页成品 简单个人网站作业模板 HTML个人网页设计下载 简约黑白色个人主页

热门文章

  1. C语言程序设计练习题解
  2. CCF201409-3 字符串匹配(100分)
  3. 【数论】—— 整数质因子分解
  4. Linux 内核源码(kernel source)路径
  5. Hopfield 神经网络及稳态性的证明
  6. 数组(有序数组)的公共部分
  7. 伸展树(splay tree)
  8. C/C++ debug(四)
  9. Python 进阶——从 list 到 NumPy 的多维数组
  10. shell 操作(四)