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; } |
总算探测到输入格式了.
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; } |
总算探测到输入格式了.
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; } |
总算探测到输入格式了.
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; } |
总算探测到输入格式了.
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; } |
总算探测到输入格式了.
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; } |
总算探测到输入格式了.