• avcodec_decode_audio2


    郑重声明:此文转自http://blog.csdn.net/cffishappy/article/details/7631424,尊重原创

    解码时发现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,后来我就顺着这个思路,往上找,过不其然,发现了问题之所在,原因是:在int len=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);
            } 
  • 相关阅读:
    15、线程
    17、lambda表达式
    16、sockect
    14、反射(reflect)
    13、集合2
    java 基本类型、包装类、字符串之间的转换
    13、集合1
    12、NIO、AIO、BIO二
    12、NIO、AIO、BIO一
    11、流与文件
  • 原文地址:https://www.cnblogs.com/wyqfighting/p/2812044.html
Copyright © 2020-2023  润新知