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