您的位置:首页 > 其它

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函数的原型:

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);
get_buffer函数, 有两处比较关键:

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);

/* 省略部分代码 */

}
fill_buffer函数, 有一处比较关键:

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);
进入av_probe_input_format2函数:

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;

}
av_match_ext函数:

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;

}

总算探测到输入格式了.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: