ffmpeg分析系列之六(再次探测输入的格式)
2013-09-06 15:10
260 查看
void *logctx= ap && ap->prealloced_context ? *ic_ptr : NULL; //
因为 ap == NULL, 所以 logctx 也 == NULL.
if (!fmt && (err = ff_probe_input_buffer(&pb, &fmt, filename, logctx, 0,
logctx ? (*ic_ptr)->probesize : 0)) < 0) {
goto fail;
}
// fmt == NULL 时才执行 ff_probe_input_buffer 函数, 因为 fmt 就等于NULL, 成立.
ff_probe_input_buffer函数的原型:
关键的代码片断:
get_buffer函数, 有两处比较关键:
fill_buffer函数, 有一处比较关键:
好了, 到第二次探测输入格式的地方了:
进入av_probe_input_format2函数:
av_match_ext函数:
总算探测到输入格式了.
因为 ap == NULL, 所以 logctx 也 == NULL.
if (!fmt && (err = ff_probe_input_buffer(&pb, &fmt, filename, logctx, 0,
logctx ? (*ic_ptr)->probesize : 0)) < 0) {
goto fail;
}
// fmt == NULL 时才执行 ff_probe_input_buffer 函数, 因为 fmt 就等于NULL, 成立.
ff_probe_input_buffer函数的原型:
int ff_probe_input_buffer(ByteIOContext **pb, // 字节IO上下文, 执行url_fopen得到的 AVInputFormat **fmt, // 输出参数: 输入的格式 const char *filename, // 文件名 void *logctx, // NULL unsigned int offset, // 0 unsigned int max_probe_size) // 0 |
/* 读待探测的数据 */ buf = av_realloc(buf, probe_size + AVPROBE_PADDING_SIZE); if ((ret = get_buffer(*pb, buf + buf_offset, probe_size - buf_offset)) < 0) { /* fail if error was not end of file, otherwise, lower score */ if (ret != AVERROR_EOF) { av_free(buf); return ret; } score = 0; ret = 0; /* error was end of file, nothing read */ } pd.buf_size += ret; pd.buf = &buf[offset]; memset(pd.buf + pd.buf_size, 0, AVPROBE_PADDING_SIZE); /* 猜测文件格式 */ *fmt = av_probe_input_format2(&pd, 1, &score); |
int get_buffer(ByteIOContext *s, unsigned char *buf, int size); { /* 省略部分代码 */ /* 读包 */ if(s->read_packet) len = s->read_packet(s->opaque, buf, size); /* 省略部分代码 */ /* 填充缓冲 */ fill_buffer(s); /* 省略部分代码 */ } |
static void fill_buffer(ByteIOContext *s) { /* 省略部分代码 */ /* 读包 */ if(s->read_packet) len = s->read_packet(s->opaque, dst, len); /* 省略部分代码 */ } |
*fmt = av_probe_input_format2(&pd, 1, &score); |
AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened, int *score_max) { AVInputFormat *fmt1, *fmt; int score; fmt = NULL; for(fmt1 = first_iformat; fmt1 != NULL; fmt1 = fmt1->next) { if (!is_opened == !(fmt1->flags & AVFMT_NOFILE)) continue; /* 这次 is_opened == 1, fmt1->flags设置AVFMT_NOFILE标志才时成立 */ /* 由于 h264_demuxer.flags == AVFMT_GENERIC_INDEX, 所以上面不成立, 继续执行 */ score = 0; if (fmt1->read_probe) { score = fmt1->read_probe(pd); /* 调用h264_demuxer.h264_probe */ } else if (fmt1->extensions) { if (av_match_ext(pd->filename, fmt1->extensions)) { /* 文件名和格式扩展名的匹配 */ /* h264_demuxer.extensions = "h26l,h264,264" */ score = 50; } } if (score > *score_max) { *score_max = score; fmt = fmt1; }else if (score == *score_max) fmt = NULL; } return fmt; } |
int av_match_ext(const char *filename, const char *extensions) { const char *ext, *p; char ext1[32], *q; if(!filename) return 0; ext = strrchr(filename, '.'); if (ext) { ext++; p = extensions; for(;;) { q = ext1; while (*p != '\0' && *p != ',' && q-ext1<sizeof(ext1)-1) *q++ = *p++; *q = '\0'; if (!strcasecmp(ext1, ext)) return 1; if (*p == '\0') break; p++; } } return 0; } |
相关文章推荐
- ffmpeg分析系列之六(再次探测输入的格式)
- ffmpeg分析系列之六(再次探测输入的格式)
- ffmpeg分析系列之四(探测输入的格式)
- ffmpeg分析系列之四(探测输入的格式)
- ffmpeg分析系列之五(打开输入的文件)
- ffmpeg分析系列之七(打开输入的流)
- ffmpeg分析系列之七(打开输入的流)
- ffmpeg分析系列之三(输入输出格式)
- ffmpeg分析系列之三(输入输出格式)
- ffmpeg分析系列之五(打开输入的文件)
- ffmpeg 如何探测网络流格式/如何从内存中获取数据,ffmpeg探测
- ffmpeg源码分析--16.bmp格式分析及raw与bmp的相互转换
- 面试问题系列:从输入网址到显示网页的全过程分析
- HTTP协议分析系列(二)------HTTP请求信息和相应信息的格式
- 媒体格式分析之flv -- 基于FFMPEG
- Storm系列(十四)架构分析之Executor-输入和输出处理
- 媒体格式分析之flv -- 基于FFMPEG
- ffmpeg源码分析--4.关于mpeg文件格式1总
- ffmpeg分析系列之一(注册编解码器)
- HDU4509 湫湫系列故事——减肥记II【格式输入+存储设置+暴力+水题】