ffmpeg为AVPacket添加解码头信息

FFmpeg解码获得的AVPacket只包含视频压缩数据,并没有包含相关的解码信息
(比如:h264的sps pps头信息,AAC的adts头信息),没有这些编码头信息解
码器(MediaCodec)是识别不到不能解码的。在FFmpeg中,这些头信息是保存
在解码器上下文(AVCodecContext)的extradata中的,所以我们需要为每一种
格式的视频添加相应的解码头信息,这样解码器(MediaCodec)才能正确解析
每一个AVPacket里的视频数据。

主要使用的类AVBitStreamFilter

添加过程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

const AVBitStreamFilter *absFilter = NULL;
AVBSFContext *absCtx = NULL;
AVCodecParameters *codecpar = NULL;

//1. 找到相应解码器的过滤器
if(strcasecmp(codecName, "h264") == 0){
absFilter = av_bsf_get_by_name("h264_mp4toannexb");
}else if(strcasecmp(codecName, "h265") == 0){
absFilter = av_bsf_get_by_name("hevc_mp4toannexb");
}

//2.过滤器分配内存
av_bsf_alloc(absFilter,absCtx)

//3. 添加解码器属性
if(pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO){
codecpar = pFormatCtx->streams[i]->codecpar;
}
avcodec_parameters_copy(absCtx->par_in, codecpar);

//4. 初始化过滤器上下文
av_bsf_init(absCtx);

//5. AVPacket处理
if(av_bsf_send_packet(absCtx, avPacket) != 0){
av_packet_free(&avPacket);
av_free(avPacket);
avPacket = NULL;
continue;
}
while(av_bsf_receive_packet(absCtx, avPacket) == 0){
LOGE("开始解码");
av_packet_free(&avPacket);
av_free(avPacket);
continue;
}
avPacket = NULL;

//6. 释放资源
av_bsf_free(&absCtx);
absCtx = NULL;

ffmpeg流过滤器列表

-------------The End-------------