ffmpeg的音频解码部分

总而言之是这样的

 

一个装音频packet的队列 这个队列是2个指针做的。

然后一个回调函数

 

主线程放包,回调取包,解码在回调里面做。

 

关键代码:

 

回调:

void audio_callback(void *userdata, Uint8 *stream, int len)
{
    AVCodecContext* aCodecCtx=(AVCodecContext*) userdata;

    int len1;
    int audio_size;

    static uint8_t audio_buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE*3)/2];
    static unsigned int audio_buf_size=0;
    static unsigned int audio_buf_index=0;

    while (len>0)
    {
        if (audio_buf_index>=audio_buf_size)
        {
            audio_size= audio_decode_frame(aCodecCtx,audio_buf,
                sizeof(audio_buf));
            if (audio_size<0)
            {
                audio_buf_size=1024;
                memset(audio_buf,0,audio_buf_size);
            }
            else
            {
                audio_buf_size=audio_size;
            }

            audio_buf_index=0;
        }

        len1=audio_buf_size-audio_buf_index;

        if (len1>len)
        {
            len1=len;
        }

        memcpy(stream,(uint8_t*)audio_buf+audio_buf_index,len1);

        len-=len1;

        stream+=len1;
        audio_buf_index+=len1;


    }

}

 

解码器 和 SDL准备就绪


    AVCodec* paCodec;

    paCodec=avcodec_find_decoder(paCodecCtx->codec_id);

    avcodec_open(paCodecCtx,paCodec);

    //准备SDL   
    //open decoder  return >0 if ok

    当然sdl你也得设置
    wanted_spec.channels= paCodecCtx->channels;
    wanted_spec.format=AUDIO_S16SYS;//格式
    wanted_spec.freq=paCodecCtx->sample_rate;
    wanted_spec.samples=SDL_AUDIO_BUFFER_SIZE;
    wanted_spec.silence=0;
    wanted_spec.userdata=paCodecCtx;
    wanted_spec.callback=audio_callback;
    // important 音频回调函数
    if(SDL_OpenAudio(&wanted_spec, &spec) < 0)
    {
       
        fprintf(stderr, "SDL_OpenAudio: %s/n", SDL_GetError());
       
        return -1;
       
    }

 

 

key:

 

int audio_decode_frame(AVCodecContext * paCodecCtx, uint8_t*  audio_buf, int buf_size)
{
//    puts("yanxinmeng ' thread");
    static AVPacket pkt;
    static uint8_t * audio_pkt_data =NULL;
    static int audio_pkt_size=0;

    int len1, data_size;

    for (;;)
    {
        while(audio_pkt_size>0)
        {
            data_size=buf_size;

            len1= avcodec_decode_audio2(paCodecCtx, (int16_t*) audio_buf,
                &data_size, audio_pkt_data,audio_pkt_size);
            if (len1<0)
            {
                audio_pkt_size=0;
                break;
            }

            audio_pkt_data+=len1;

            audio_pkt_size-=len1;
            if (data_size<=0)
            {
                continue;
            }

            return data_size;
        }

        if(pkt.data)

            av_free_packet(&pkt);

        if (quit)
        {
            return -1;
        }

        if (packet_queue_get(&audioQueue,&pkt,1)<0)
        {
            return -1;
        }

        audio_pkt_data= pkt.data;

        audio_pkt_size=pkt.size;
    }
}


转自 http://blog.youkuaiyun.com/loving_handi/article/details/5065308

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值