FFMPeg代码分析:AVFormatContext结构体
来源:互联网 发布:mblock编程语言 编辑:程序博客网 时间:2024/05/18 06:27
转自:http://blog.csdn.net/shaqoneal/article/details/16879951
从先前的demo中可以看到,进入main函数所定义的第一个变量就是AVFormatContext的指针:
- int main(int argc, char *argv[])
- {
- AVFormatContext *pFormatCtx = NULL;
- ....
- }
- typedef struct AVFormatContext
- {
- const AVClass *av_class;
- struct AVInputFormat *iformat;
- struct AVOutputFormat *oformat;
- void *priv_data;
- AVIOContext *pb;
- int ctx_flags;
- unsigned int nb_streams;
- AVStream **streams;
- char filename[1024];
- int64_t start_time;
- int64_t duration;
- int bit_rate;
- unsigned int packet_size;
- int max_delay;
- int flags;
- #define AVFMT_FLAG_GENPTS 0x0001 ///< Generate missing pts even if it requires parsing future frames.
- #define AVFMT_FLAG_IGNIDX 0x0002 ///< Ignore index.
- #define AVFMT_FLAG_NONBLOCK 0x0004 ///< Do not block when reading packets from input.
- #define AVFMT_FLAG_IGNDTS 0x0008 ///< Ignore DTS on frames that contain both DTS & PTS
- #define AVFMT_FLAG_NOFILLIN 0x0010 ///< Do not infer any values from other values, just return what is stored in the container
- #define AVFMT_FLAG_NOPARSE 0x0020 ///< Do not use AVParsers, you also must set AVFMT_FLAG_NOFILLIN as the fillin code works on frames and no parsing -> no frames. Also seeking to frames can not work if parsing to find frame boundaries has been disabled
- #define AVFMT_FLAG_NOBUFFER 0x0040 ///< Do not buffer frames when possible
- #define AVFMT_FLAG_CUSTOM_IO 0x0080 ///< The caller has supplied a custom AVIOContext, don't avio_close() it.
- #define AVFMT_FLAG_DISCARD_CORRUPT 0x0100 ///< Discard frames marked corrupted
- #define AVFMT_FLAG_FLUSH_PACKETS 0x0200 ///< Flush the AVIOContext every packet.
- #define AVFMT_FLAG_MP4A_LATM 0x8000 ///< Enable RTP MP4A-LATM payload
- #define AVFMT_FLAG_SORT_DTS 0x10000 ///< try to interleave outputted packets by dts (using this flag can slow demuxing down)
- #define AVFMT_FLAG_PRIV_OPT 0x20000 ///< Enable use of private options by delaying codec open (this could be made default once all code is converted)
- #define AVFMT_FLAG_KEEP_SIDE_DATA 0x40000 ///< Don't merge side data but keep it separate.
- unsigned int probesize;
- int max_analyze_duration;
- const uint8_t *key;
- int keylen;
- unsigned int nb_programs;
- AVProgram **programs;
- enum AVCodecID video_codec_id;
- enum AVCodecID audio_codec_id;
- enum AVCodecID subtitle_codec_id;
- unsigned int max_index_size;
- unsigned int max_picture_buffer;
- unsigned int nb_chapters;
- AVChapter **chapters;
- AVDictionary *metadata;
- int64_t start_time_realtime;
- int fps_probe_size;
- int error_recognition;
- AVIOInterruptCB interrupt_callback;
- int debug;
- #define FF_FDEBUG_TS 0x0001
- int ts_id;
- int audio_preload;
- int max_chunk_duration;
- int max_chunk_size;
- int use_wallclock_as_timestamps;
- int avoid_negative_ts;
- int avio_flags;
- enum AVDurationEstimationMethod duration_estimation_method;
- unsigned int skip_initial_bytes;
- unsigned int correct_ts_overflow;
- int seek2any;
- int flush_packets;
- int probe_score;
- } AVFormatContext;
const AVClass *av_class:用于记录日志和设置AVOption的类,由avformat_alloc_context()设置。AVClass类中保存了包含该成员的类名、对象名和AVOption实例等信息;
AVInputFormat *iformat / AVOutputFormat *oformat:输入/输出格式,或为输入或为输出,这两个不能同时存在;分别用于编码和解码。AVOutputFormat类保存了文件名、扩展名、默认音视频和字幕解码器等信息;
void *priv_data:私有数据,只有iformat/oformat.priv_class非0时有效;
AVIOContext *pb:指向IO数据的缓存的指针;
int ctx_flags:媒体流信息;
unsigned int nb_streams:包含的媒体流的数量;
AVStream **streams:指向实际输入/输出数据的指针;
char filename[1024]:输入或输出的文件名;
int64_t start_time / int64_t duration:媒体的开始时间和持续时长,一般由AVStream **streams导出;
int bit_rate:视频码率,由ffmpeg自动计算;
unsigned int packet_size:包尺寸;
int max_delay:最大延迟;
unsigned int probesize:在解码时用于探测的数据的大小,编码时不使用;
int max_analyze_duration:允许输入数据在avformat_find_stream_info()中分析的最长时间;
const uint8_t *key:关键字;
int keylen:关键字长;
unsigned int nb_programs:包含节目的数量;
AVProgram **programs:指向实际节目的指针;
enum AVCodecID video_codec_id:指定的视频解码器ID;由用户指定;
enum AVCodecID audio_codec_id:指定的音频解码器ID;由用户指定;
enum AVCodecID subtitle_codec_id:指定的字幕解码器ID;由用户指定;
unsigned int max_index_size:用于检索码流的索引值的最大字长;
unsigned int max_picture_buffer:图像缓存的最大尺寸;
unsigned int nb_chapters:章节数目;
AVChapter **chapters:指向章节数据的指针;
AVDictionary *metadata:元数据;
int64_t start_time_realtime;:码流开始的实际时间,以毫秒为单位;
int fps_probe_size:表明使用了多少帧用于格式检测;
int error_recognition:错误检测的阈值;
AVIOInterruptCB interrupt_callback:在IO层用户自定义的回调结构;
int ts_id:传输流的ID;
unsigned int skip_initial_bytes:打开媒体流时跳过的字节数;
int seek2any:是否可以移动到任意一帧的位置;
int flush_packets:每处理一个packet之后刷新io上下文;
int probe_score:格式探测的分值,上限为AVPROBE_SCORE_MAX;
指向元数据的结构体AVDictionary由两部分组成:统计计数和指向AVDictionaryEntry的指针,也就是说AVDictionary可以说是AVDictionaryEntry的封装。
- struct AVDictionary
- {
- int count;
- AVDictionaryEntry *elems;
- };
- typedef struct AVDictionaryEntry
- {
- char *key;
- char *value;
- } AVDictionaryEntry;
了解了AVFormatContext的构造之后,可以再来看看它是如何被初始化的了。在函数avformat_open_input中,AVFormatContext的初始化由avformat_alloc_context()及其调用的函数实现:
- AVFormatContext *avformat_alloc_context(void)
- {
- AVFormatContext *ic;
- ic = av_malloc(sizeof(AVFormatContext));
- if (!ic) return ic;
- avformat_get_context_defaults(ic);
- return ic;
- }
- static void avformat_get_context_defaults(AVFormatContext *s)
- {
- memset(s, 0, sizeof(AVFormatContext));
- s->av_class = &av_format_context_class;
- av_opt_set_defaults(s);
- }
- void av_opt_set_defaults(void *s)
- {
- #if FF_API_OLD_AVOPTIONS
- av_opt_set_defaults2(s, 0, 0);
- }
- void av_opt_set_defaults2(void *s, int mask, int flags)
- {
- #endif
- const AVClass *class = *(AVClass **)s;
- const AVOption *opt = NULL;
- while ((opt = av_opt_next(s, opt)) != NULL) {
- #if FF_API_OLD_AVOPTIONS
- if ((opt->flags & mask) != flags)
- continue;
- #endif
- switch (opt->type) {
- case AV_OPT_TYPE_CONST:
- /* Nothing to be done here */
- break;
- case AV_OPT_TYPE_FLAGS:
- case AV_OPT_TYPE_INT:
- case AV_OPT_TYPE_INT64:
- case AV_OPT_TYPE_DURATION:
- case AV_OPT_TYPE_CHANNEL_LAYOUT:
- av_opt_set_int(s, opt->name, opt->default_val.i64, 0);
- break;
- case AV_OPT_TYPE_DOUBLE:
- case AV_OPT_TYPE_FLOAT: {
- double val;
- val = opt->default_val.dbl;
- av_opt_set_double(s, opt->name, val, 0);
- }
- break;
- case AV_OPT_TYPE_RATIONAL: {
- AVRational val;
- val = av_d2q(opt->default_val.dbl, INT_MAX);
- av_opt_set_q(s, opt->name, val, 0);
- }
- break;
- case AV_OPT_TYPE_COLOR:
- case AV_OPT_TYPE_STRING:
- case AV_OPT_TYPE_IMAGE_SIZE:
- case AV_OPT_TYPE_VIDEO_RATE:
- av_opt_set(s, opt->name, opt->default_val.str, 0);
- break;
- case AV_OPT_TYPE_PIXEL_FMT:
- #if LIBAVUTIL_VERSION_MAJOR < 53
- if (class->version && class->version < AV_VERSION_INT(52, 10, 100))
- av_opt_set(s, opt->name, opt->default_val.str, 0);
- else
- #endif
- av_opt_set_pixel_fmt(s, opt->name, opt->default_val.i64, 0);
- break;
- case AV_OPT_TYPE_SAMPLE_FMT:
- #if LIBAVUTIL_VERSION_MAJOR < 53
- if (class->version && class->version < AV_VERSION_INT(52, 10, 100))
- av_opt_set(s, opt->name, opt->default_val.str, 0);
- else
- #endif
- av_opt_set_sample_fmt(s, opt->name, opt->default_val.i64, 0);
- break;
- case AV_OPT_TYPE_BINARY:
- /* Cannot set default for binary */
- break;
- default:
- av_log(s, AV_LOG_DEBUG, "AVOption type %d of option %s not implemented yet\n", opt->type, opt->name);
- }
- }
- }
可以看到,在av_opt_set_defaults2()函数中,首先会调用av_opt_next(s, opt),并根据opt->type的不同值来进行下一步的设置。av_opt_next()的代码:
- const AVOption *av_opt_next(void *obj, const AVOption *last)
- {
- AVClass *class = *(AVClass**)obj;
- if (!last && class && class->option && class->option[0].name)
- return class->option;
- if (last && last[1].name)
- return ++last;
- return NULL;
- }
- int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags)
- {
- return set_number(obj, name, 1, 1, val, search_flags);
- }
- static int set_number(void *obj, const char *name, double num, int den, int64_t intnum, int search_flags)
- {
- void *dst, *target_obj;
- const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
- if (!o || !target_obj)
- return AVERROR_OPTION_NOT_FOUND;
- dst = ((uint8_t*)target_obj) + o->offset;
- return write_number(obj, o, dst, num, den, intnum);
- }
- FFMPeg代码分析:AVFormatContext结构体
- FFMPeg代码分析:AVFormatContext结构体
- FFMPEG结构体分析:AVFormatContext
- FFMPEG结构体分析:AVFormatContext
- FFMPEG结构体分析:AVFormatContext
- FFMPEG结构体分析:AVFormatContext
- FFMPEG结构体分析 AVFormatContext
- FFMPEG结构体分析:AVFormatContext
- FFMPEG结构体分析:AVFormatContext
- FFMPEG结构体分析:AVFormatContext
- FFMPEG结构体分析:AVFormatContext
- FFMPEG结构体分析:AVFormatContext
- FFMPEG结构体分析一:AVFormatContext
- (13) FFMPEG结构体分析:AVFormatContext
- FFmpeg中结构体AVFormatContext
- ffmpeg之AVFormatContext结构体
- FFMpeg学习笔记 AVFormatContext结构分析
- Ffmpeg结构体——AVFormatContext
- 备份Ubuntu12.04 并制作成iso安装文件
- 关于Draw Something的一些分析
- 【python系列】python编程中几个实用的技巧
- ArcGIS Server10.1的缓存目录放在几台机器上的方法
- Windows Server 2008 流媒体服务器配置手册(一)
- FFMPeg代码分析:AVFormatContext结构体
- js的\u汉字编码转化为java可识别的
- css中font的简写方式
- ANDROID application详解与用法
- 特征向量几何意义
- **没有规则可以创建“XXX”需要的目标“XXX”问题的解决方案
- 一个手游人眼中的2014:并购转向、淘汰高发、借4G飙高
- 使用Application维护管理Activity列表
- python import