查找编码器
AVCodecParserContext *av_parser_init(int codec_id);
实现
AVCodecParserContext *av_parser_init(int codec_id) { AVCodecParserContext *s = NULL; const AVCodecParser *parser; void *i = 0; int ret; if (codec_id == AV_CODEC_ID_NONE) return NULL; // 1.基于id查找AVCodecParser解析器 while ((parser = av_parser_iterate(&i))) { if (parser->codec_ids[0] == codec_id || parser->codec_ids[1] == codec_id || parser->codec_ids[2] == codec_id || parser->codec_ids[3] == codec_id || parser->codec_ids[4] == codec_id) goto found; } return NULL; found: // 2.分配解析器上下文 s = av_mallocz(sizeof(AVCodecParserContext)); if (!s) goto err_out; // 3.解析器上下文初始化 s->parser = (AVCodecParser*)parser; s->priv_data = av_mallocz(parser->priv_data_size); if (!s->priv_data) goto err_out; s->fetch_timestamp=1; s->pict_type = AV_PICTURE_TYPE_I; // 4.解析器初始化 if (parser->parser_init) { ret = parser->parser_init(s); if (ret != 0) goto err_out; } s->key_frame = -1; #if FF_API_CONVERGENCE_DURATION FF_DISABLE_DEPRECATION_WARNINGS s->convergence_duration = 0; FF_ENABLE_DEPRECATION_WARNINGS #endif s->dts_sync_point = INT_MIN; s->dts_ref_dts_delta = INT_MIN; s->pts_dts_delta = INT_MIN; s->format = -1; return s; err_out: // 5.查找失败,释放priv_data 返回NULL if (s) av_freep(&s->priv_data); av_free(s); return NULL; }
const AVCodecParser *av_parser_iterate(void **opaque) { uintptr_t i = (uintptr_t)*opaque; const AVCodecParser *p = parser_list[i]; if (p) *opaque = (void*)(i + 1); return p; }
这里主要分为几步:
- 基于id查找AVCodecParser解析器,可以发现就在parser_list数组里找的
- 分配解析器上下文
- 解析器上下文初始化
- 解析器初始化
- 查找失败,释放priv_data 返回NULL