avcodec_decode_audio2返回值为-1?

我用ffmpeg4.0版本代替旧版本3.2时,解码时发现avcodec_decode_audio2返回值总为-1,我程序中代码如下:

        int out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;     //#define AVCODEC_MAX_AUDIO_FRAME_SIZE 2<<20 
        uint8_t * inbuf = (uint8_t *)malloc(out_size);
        FILE* pFileWav;
        int fileSize; 
        pFileWav= fopen("b.pcm","wb+");
        while(av_read_frame(pFormatCtx, &packet)>=0)
        {
               if(packet.stream_index==audioStream) {
                       pktdata = packet.data;
                       pktsize = packet.size;
                       while(pktsize>0)
                       {
                               //解码
                               int len=avcodec_decode_audio2(pCodecCtx,(int16_t *)inbuf,&out_size,pktdata,pktsize);
//                             int len=avcodec_decode_audio3(pCodecCtx,(int16_t *)inbuf,&out_size,&packet);
                               if (len<0)
                               {
                                      printf("Error while decoding.\n");
                                      break;
                               }
                               if(out_size>0)
                               {
                                      fwrite(inbuf,1,out_size,pFileWav);//pcm记录
                                      fflush(pFileWav);
                                      fileSize += out_size;
                               }
                               pktsize -= len;
                               pktdata += len;
                       }
               }   
               av_free_packet(&packet);
        }   


 

后来查了下ffmpeg3.2源代码,发现:

int avcodec_decode_audio(AVCodecContext *avctx, int16_t *samples,
                         int *frame_size_ptr,
                         const uint8_t *buf, int buf_size){
    *frame_size_ptr= AVCODEC_MAX_AUDIO_FRAME_SIZE;
    return avcodec_decode_audio2(avctx, samples, frame_size_ptr, buf, buf_size);
}
 
int attribute_align_arg avcodec_decode_audio2(AVCodecContext *avctx, int16_t *samples,
                         int *frame_size_ptr,
                         const uint8_t *buf, int buf_size)
{
    int ret;
 
    if((avctx->codec->capabilities & CODEC_CAP_DELAY) || buf_size){
        //FIXME remove the check below _after_ ensuring that all audio check that the available space is enough
        if(*frame_size_ptr < AVCODEC_MAX_AUDIO_FRAME_SIZE){
            av_log(avctx, AV_LOG_ERROR, "buffer smaller than AVCODEC_MAX_AUDIO_FRAME_SIZE\n");
            return -1;
        }
        if(*frame_size_ptr < FF_MIN_BUFFER_SIZE ||
        *frame_size_ptr < avctx->channels * avctx->frame_size * sizeof(int16_t)){
            av_log(avctx, AV_LOG_ERROR, "buffer %d too small\n", *frame_size_ptr);
            return -1;
        }
 
        ret = avctx->codec->decode(avctx, samples, frame_size_ptr,
                                buf, buf_size);
        avctx->frame_number++;
    }else{
        ret= 0;
        *frame_size_ptr=0;
    }
    return ret;
}

ffmpeg4.0中代码为:

int attribute_align_arg avcodec_decode_audio2(AVCodecContext *avctx, int16_t *samples,
                         int *frame_size_ptr,
                         const uint8_t *buf, int buf_size)
{
    AVPacket avpkt;
    av_init_packet(&avpkt);
    avpkt.data = buf;
    avpkt.size = buf_size;
 
    return avcodec_decode_audio3(avctx, samples, frame_size_ptr, &avpkt);
}
#endif
 
int attribute_align_arg avcodec_decode_audio3(AVCodecContext *avctx, int16_t *samples,
                         int *frame_size_ptr,
                         AVPacket *avpkt)
{
    int ret;
 
    if((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size){
        //FIXME remove the check below _after_ ensuring that all audio check that the available space is enough
        if(*frame_size_ptr < AVCODEC_MAX_AUDIO_FRAME_SIZE){
            av_log(avctx, AV_LOG_ERROR, "buffer smaller than AVCODEC_MAX_AUDIO_FRAME_SIZE\n");
            return -1;
        }
        if(*frame_size_ptr < FF_MIN_BUFFER_SIZE ||
        *frame_size_ptr < avctx->channels * avctx->frame_size * sizeof(int16_t)){
            av_log(avctx, AV_LOG_ERROR, "buffer %d too small\n", *frame_size_ptr);
            return -1;
        }
 
        ret = avctx->codec->decode(avctx, samples, frame_size_ptr, avpkt);
        avctx->frame_number++;
    }else{
        ret= 0;
        *frame_size_ptr=0;
    }
    return ret;
}

 

即每次调用avcodec_decode_audio2时,若(*frame_size_ptr < AVCODEC_MAX_AUDIO_FRAME_SIZE),则返回值为-1,后来我就顺着这个思路,往上找,过不其然,发现了问题之所在,原因是:在intlen=avcodec_decode_audio2(pCodecCtx,(int16_t *)inbuf,&out_size,pktdata,pktsize)处理后,out_size的值变为4608,而不是AVCODEC_MAX_AUDIO_FRAME_SIZE,所以在4.0中,*frame_size_ptr < AVCODEC_MAX_AUDIO_FRAME_SIZE,返回值自然为-1

找到了问题,解决自然容易,要么在ffmpeg源码处该,要么在客户端,而我选择了后者,主要是方便:

int out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
        uint8_t * inbuf = (uint8_t *)malloc(out_size);
 
        FILE* pFileWav;
        int fileSize; 
        pFileWav= fopen("b.pcm","wb+");
        while(av_read_frame(pFormatCtx, &packet)>=0)
        {
               if(packet.stream_index==audioStream) {
                       pktdata = packet.data;
                       pktsize = packet.size;
                       out_size=AVCODEC_MAX_AUDIO_FRAME_SIZE;    //加这一句,就OK
                       while(pktsize>0)
                       {
                               //解码
                               int len=avcodec_decode_audio2(pCodecCtx,(int16_t *)inbuf,&out_size,pktdata,pktsize);
//                             int len=avcodec_decode_audio3(pCodecCtx,(int16_t *)inbuf,&out_size,&packet);
                               if (len<0)
                               {
                                      printf("Error while decoding.\n");
                                      break;
                               }
                               if(out_size>0)
                               {
                                      fwrite(inbuf,1,out_size,pFileWav);//pcm记录
                                      fflush(pFileWav);
                                      fileSize += out_size;
                               }
                               pktsize -= len;
                               pktdata += len;
                       }
               }   
               av_free_packet(&packet);
        } 


 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值