ffmpeg播放视频音频(ffmpeg 3.0之前老版本)

void CProgram::Test()
{
    avcodec_init();
    av_register_all();

    AVFormatContext *pFormatCtx; 
    int i, videoStream; 
    int audioStream; 

    const char *input_file_name = "F:\\fashion_100M.ts"; 

    // Open video file 
    if(av_open_input_file(&pFormatCtx, input_file_name, NULL, 0, NULL)!=0) 
        return ; 

    // Retrieve stream information 
    if(av_find_stream_info(pFormatCtx) < 0) 
        return ; 

    // Find the first video stream 
    videoStream = -1; 
    audioStream = -1; 
    for(i = 0; i < pFormatCtx->nb_streams; i++) 
    { 
        if(pFormatCtx->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO) 
        { 
            videoStream = i; 
        } 
        else if(pFormatCtx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO) 
        { 
            audioStream = i; 
        } 
    } 
    if(videoStream == -1) 
    { 
        return ; 
    } 

    AVCodecContext  *pVideoCodecCtx=pFormatCtx->streams[videoStream]->codec;
    AVCodec         *pVideoCodec=avcodec_find_decoder(pVideoCodecCtx->codec_id);

    AVCodecContext  *pAudioCodecCtx=pFormatCtx->streams[audioStream]->codec;
    AVCodec         *pAudioCodec=avcodec_find_decoder(pAudioCodecCtx->codec_id);


    //打开视频解码器
    if(avcodec_open(pVideoCodecCtx,pVideoCodec) < 0)
    {
        return ; 
    }

    //通知解码器,我们能处理截断的bit流
    if (pAudioCodec->capabilities&CODEC_CAP_TRUNCATED)
    {
        pAudioCodecCtx->flags|=CODEC_FLAG_TRUNCATED;
    }

    //打开音频解码器
    if(avcodec_open(pAudioCodecCtx,pAudioCodec) < 0)
    {
        return ; 
    }

    uint8_t *pktdata;
    int pktsize;
    int out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
    uint8_t * inbuf = (uint8_t *)malloc(out_size);


    int nRet=0;
    int nGopPicture=1;
    int nFrameCount=0;
    int nLostFrame=0;

    AVPacket pktData;
    av_init_packet(&pktData);

    while(av_read_frame(pFormatCtx, &pktData) >= 0) 
    { 
        if(pktData.stream_index == videoStream) 
        { 
            AVFrame *pFrame1=avcodec_alloc_frame();

                //解码视频
                nRet=avcodec_decode_video(pVideoCodecCtx,pFrame1,&nGopPicture,pktData.data,pktData.size);

                if ( nGopPicture > 0 )
                {
                                           //将解码出的YUV数据拷贝到自己分配的节点中
                    PYUV_FRAME pYUVFrame=new YUV_FRAME;

                    pYUVFrame->pYFrame=new unsigned char[m_stFileEncodeInfo.pVideoCodecCtx->width*m_stFileEncodeInfo.pVideoCodecCtx->height];
                    pYUVFrame->pUFrame=new unsigned char[m_stFileEncodeInfo.pVideoCodecCtx->width*m_stFileEncodeInfo.pVideoCodecCtx->height/4];
                    pYUVFrame->pVFrame=new unsigned char[m_stFileEncodeInfo.pVideoCodecCtx->width*m_stFileEncodeInfo.pVideoCodecCtx->height/4];

                    unsigned char *pY=pYUVFrame->pYFrame;
                    unsigned char *pU=pYUVFrame->pUFrame;
                    unsigned char *pV=pYUVFrame->pVFrame;

                    //拷贝Y数据
                    for (int i=0;i<m_stFileEncodeInfo.pVideoCodecCtx->height;i++)
                    {
                        memcpy(pY,pFrame1->data[0], m_stFileEncodeInfo.pVideoCodecCtx->width);
                        pFrame1->data[0]+=pFrame1->linesize[0];
                        pY+=m_stFileEncodeInfo.pVideoCodecCtx->width;
                    }

                    //拷贝U数据
                    for (int i=0;i<m_stFileEncodeInfo.pVideoCodecCtx->height/2;i++)
                    {
                        memcpy(pU,pFrame1->data[1], m_stFileEncodeInfo.pVideoCodecCtx->width/2);
                        pFrame1->data[1]+=pFrame1->linesize[1];
                        pU+=m_stFileEncodeInfo.pVideoCodecCtx->width/2;
                    }

                    //拷贝V数据
                    for (int i=0;i<m_stFileEncodeInfo.pVideoCodecCtx->height/2;i++)
                    {
                        memcpy(pV,pFrame1->data[2], m_stFileEncodeInfo.pVideoCodecCtx->width/2);
                        pFrame1->data[2]+=pFrame1->linesize[2];
                        pV+=m_stFileEncodeInfo.pVideoCodecCtx->width/2;
                    }
               
                                           //将节点保存到链表中供DirectDraw显示
                    m_videoPlay.m_csVideoQueueSection.Lock();
                    m_videoPlay.m_listVideoFrame.AddTail(pYUVFrame);
                    m_videoPlay.m_csVideoQueueSection.Unlock();

                    nFrameCount++;
                    TRACE("nGopPicture > 0  成功解码!  %d 帧,nGopPicture值为 %d ,nRet值为 %d ,输入包长为 %d \n",nFrameCount,nGopPicture,nRet,pktData.size);

                }
                else 
                {
                    nLostFrame++;
                    TRACE("-----丢失帧的总数为 %d ,nGopPicture值为 %d ,nRet值为 %d,输入包长为 %d----\n",nLostFrame,nGopPicture,nRet,pktData.size);

                }

            av_free(pFrame1);
        } 
        else if(pktData.stream_index == audioStream) 
        { 
            //解码音频
            int nInSize=pktData.size;
            unsigned char *pInBuff=pktData.data;

            int outSize=AVCODEC_MAX_AUDIO_FRAME_SIZE;
            unsigned char *pOutBuff=new unsigned char[outSize];
            memset(pOutBuff,0,AVCODEC_MAX_AUDIO_FRAME_SIZE);

            nRet=avcodec_decode_audio2(m_stFileEncodeInfo.pAudioCodecCtx,(short*)pOutBuff,&outSize,pInBuff,nInSize);

            if (nRet >= 0)
            {
                                    //将解码得到的PCM数据保存到缓冲区中中供DirectSound播放
                m_audioPlay.m_audioRingBuff.InputData(pOutBuff,outSize);
            }

            delete[] pOutBuff;
            pOutBuff=NULL;

        } 
        // Free the packet that was allocated by av_read_frame 
        av_free_packet(&pktData); 
    } 

    av_close_input_file(pFormatCtx); 

};
阅读更多
个人分类: ffmpeg
想对作者说点什么? 我来说一句

qt+ffmpeg播放音视频

2017年08月29日 125KB 下载

版本FFmpeg动态库

2018年03月24日 12.57MB 下载

FFMPEG的历史版本版本号1.0

2016年09月02日 7.52MB 下载

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭