1、 av_dict_get 的正确用法
正确用法1: AVDictionaryEntry *tag = NULL;
tag = av_dict_get(st->metadata, “width”, tag, AV_DICT_MATCH_CASE);
正确用法2:AVDictionaryEntry *tag = av_dict_get(st->metadata, “width”, NULL, AV_DICT_MATCH_CASE);
标准的错误用法:
AVDictionaryEntry *tag = av_dict_get(st->metadata, “width”, tag, AV_DICT_MATCH_CASE);
此时tag没有初始化,极大可能是一个指向随机地址的随机值。
而 av_dict_get实现如下:
AVDictionaryEntry *av_dict_get(const AVDictionary *m, const char *key,
const AVDictionaryEntry *prev, int flags)
{
unsigned int i, j;
if (!m)
return NULL;
if (prev)
i = prev - m->elems + 1;
else
i = 0;
for (; i < m->count; i++) {
const char *s = m->elems[i].key;
if (flags & AV_DICT_MATCH_CASE)
for (j = 0; s[j] == key[j] && key[j]; j++)
;
else
for (j = 0; av_toupper(s[j]) == av_toupper(key[j]) && key[j]; j++)
;
if (key[j])
continue;
if (s[j] && !(flags & AV_DICT_IGNORE_SUFFIX))
continue;
return &m->elems[i];
}
return NULL;
}
通过
if (prev)
i = prev - m->elems + 1;
获取的i值极有可能是一个超过 m->count 的值,导致ffmpeg内部设置的键值,外部获取不到,哎~~~
2、又犯了一个低级错误
libavformat/mov.c中
static int mov_read_close(AVFormatContext *s)
{
MOVContext *mov = s->priv_data;
int i, j;
for (i = 0; i < s->nb_streams; i++) {
AVStream *st = s->streams[i];
MOVStreamContext *sc = st->priv_data;
if (!sc)
continue;
av_freep(&sc->ctts_data);
for (j = 0; j < sc->drefs_count; j++) {
av_freep(&sc->drefs[j].path);
av_freep(&sc->drefs[j].dir);
}
av_freep(&sc->drefs);
…………
}
}
对AVStream内部的资源释放时,for循环的技术用的是j
我没有审视上下文,偏偏搞了一个i计数,导致直接死循环。
结论:coding不仔细,debug怪水逆啊!!
coding时,一定要自己,一定要与上下文的风格保持一致,
从形式上讲,代码会变得很美观;
从内容上讲,可以避免吃好多苦。
戒骄戒躁,砥砺前行。