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;
ffmpeg流過濾器列表