如何使用avcodec_decode_audio4解码AAC? [英] How to decode AAC using avcodec_decode_audio4?

查看:341
本文介绍了如何使用avcodec_decode_audio4解码AAC?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将我的代码avcodec_decode_audio3更改为avcodec_decode_audio4,并添加了帧处理。但是现在我无法解码AAC帧了。



为什么avcodec_decode_audio4返回 -22 无效参数)?
按照以下答案,这是否与需要设置的AVContext中的参数有关?



我不得不使用avcodec_decode_audio4,因为我更新了ffmpeg然后得到以下错误:

  [NULL @ 0xb14f020]检测到使用withavcodec_decode_audio3()的自定义get_buffer() 
使用avcodec_default_get_buffer覆盖
[NULL @ 0xb14f020]请将应用程序移植到avcodec_decode_audio4()

根据 avcodec_decode_audio4()中的缓冲区错误,这是一个回归,有没有其他的解决方案,而不是回到ffmpeg< 0.8?



使用avcodec_decode_audio4的解码器:

  AVCodec * 
AVCodecContext * avCtx;
AVFrame * decoded_frame = NULL;
uint8_t * outbuf = static_cast< uint8_t *>(malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE));
AVPacket avPacket;

main(){
av_register_all();
codec = avcodec_find_decoder(CODEC_ID_AAC);

//设置参数
avCtx = avcodec_alloc_context3(codec);
avCtx-> channels = 1;
avCtx-> sample_rate = 44100;
avCtx-> bit_rate = 16;

if(avcodec_open2(avCtx,codec,NULL)< 0)printf(无法打开codec\\\
);

av_init_packet(& avPacket);

//主解码器循环
while(1)
my_frame_decoder();
return 0;
}

void my_frame_decoder(){
//获取数据
...
avPacket.size = numBytes;
avPacket.data = inputBytes;
int len;

while(avPacket.size> 0){

int got_frame = 0;
if(!decoded_frame){
if(!(decoded_frame = avcodec_alloc_frame())){
printf(out of memory);
返回;
}
} else {
avcodec_get_frame_defaults(decoded_frame);
}

// -------------------->>返回始终为-22
len = avcodec_decode_audio4(avCtx,decoded_frame,& got_frame,& avPacket);

//用解码的帧执行某些操作
...
avPacket.size - = len;
avPacket.data + = len;
}

return;
}


解决方案

发现 avcodec_decode_audio4 dec_ctx 必须由 dec_codec 初始化为 av_find_best_stream()

  1°av_find_best_stream(in_fmt_ctx ,AVMEDIA_TYPE_AUDIO,-1,-1,
& dec_codec,0);< br>
2°dec_ctx = m_in_aud_strm-> codec;< br>
3°av_opt_set_int(dec_ctx,refcounted_frames,1,0);< br>
4°avcodec_open2(dec_ctx,dec_codec,NULL)< br>



5°avcodec_decode_audio4(dec_ctx,pFrame,& got_frame,& pkt);


I changed in my code avcodec_decode_audio3 to avcodec_decode_audio4 and added the frame handling. But now I cannot decode AAC frames anymore.

Why does avcodec_decode_audio4 return -22 (invalid argument)? Following the answer below, does this have something to do with the parameters in AVContext that need to be set?

I had to use avcodec_decode_audio4 because I updated my ffmpeg and then got the following error:

[NULL @ 0xb14f020] Custom get_buffer() for use withavcodec_decode_audio3() detected. 
         Overriding with avcodec_default_get_buffer
[NULL @ 0xb14f020] Please port your application to avcodec_decode_audio4()

According to Buffer error in avcodec_decode_audio4() this is a regression, is there any other solution for this than going back to ffmpeg < 0.8 ?

The decoder using avcodec_decode_audio4:

AVCodec *codec;
AVCodecContext *avCtx;
AVFrame * decoded_frame = NULL;
uint8_t *outbuf = static_cast<uint8_t *>(malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE));
AVPacket avPacket;

main(){
    av_register_all();
    codec = avcodec_find_decoder(CODEC_ID_AAC);

    //set parameters
    avCtx = avcodec_alloc_context3(codec);
    avCtx->channels = 1;
    avCtx->sample_rate = 44100;
    avCtx->bit_rate=16;

    if (avcodec_open2(avCtx, codec, NULL) < 0) printf("Could not open codec\n");

    av_init_packet(&avPacket);

    //Main decoder loop
    while(1) 
        my_frame_decoder();
    return 0;
}

void my_frame_decoder() {
    //get data
    ...
    avPacket.size = numBytes;
    avPacket.data = inputBytes;
    int len;

    while (avPacket.size > 0) {

    int got_frame = 0;
    if (!decoded_frame) {
        if (!(decoded_frame = avcodec_alloc_frame())) {
            printf("out of memory");
            return;
        }
    } else {
        avcodec_get_frame_defaults(decoded_frame);
    }

    //-------------------->> returns always -22
    len = avcodec_decode_audio4(avCtx, decoded_frame, &got_frame, &avPacket); 

    //do something with the decoded frame
    ...
    avPacket.size -= len;
    avPacket.data += len;
    }

    return;
}

解决方案

After hours of searching, i found out that the dec_ctx of the avcodec_decode_audio4 must be opened by a dec_codec initialised by av_find_best_stream()

1° av_find_best_stream(in_fmt_ctx, AVMEDIA_TYPE_AUDIO, -1, -1,
                &dec_codec, 0);<br>
2° dec_ctx = m_in_aud_strm->codec;<br>
3° av_opt_set_int(dec_ctx, "refcounted_frames", 1, 0);<br>
4° avcodec_open2(dec_ctx, dec_codec, NULL)<br>
.
.
.
5° avcodec_decode_audio4(dec_ctx, pFrame, &got_frame, &pkt);

这篇关于如何使用avcodec_decode_audio4解码AAC?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆