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

转载 2012年03月29日 16:48:58
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); 

};

第一次用ffplay播放视频的过程以及ffplay使用说明书

第一次用ffplay播放视频的过程以及ffplay使用说明书

100行代码实现最简单的基于FFMPEG+SDL的视频播放器(SDL1.x)

FFMPEG工程浩大,可以参考的书籍又不是很多,因此很多刚学习FFMPEG的人常常感觉到无从下手。我刚接触FFMPEG的时候也感觉不知从何学起。 因此我把自己做项目过程中实现的一个非常简单的视频播放器...

Ffplay视频播放流程

背景说明 FFmpeg是一个开源,免费,跨平台的视频和音频流方案,它提供了一套完整的录制、转换以及流化音视频的解决方案。而ffplay是有ffmpeg官方提供的一个基于ffmpeg的简单播放器。学习f...
  • nfer_cn
  • nfer_cn
  • 2013年12月24日 09:37
  • 8427

FFmpeg 3.0 版发布

本文译至:https://osdn.jp/magazine/16/02/16/155500 开源多媒体框架「FFmpeg」开发团队于2月15日,发布最新稳定版「FFmpeg 3.0」(代号「Eins...

最新(2.44)FFmpeg音频播放 ----- 关键点swr_convert

关于音频转换 swr_convert 有些旧的ffmpeg播放音频示例中,会存在一些音频可以播放一些不能播放,其中一个我们需要考虑的原因和该注意的地方就是 av_decode_audiole类似函数...

[总结]FFMPEG视音频编解码零基础学习方法

在CSDN上的这一段日子,接触到了很多同行业的人,尤其是使用FFMPEG进行视音频编解码的人,有的已经是有多年经验的“大神”,有的是刚开始学习的初学者。在和大家探讨的过程中,我忽然发现了一个问题:在“...

最简单的基于FFMPEG+SDL的音频播放器

FFMPEG工程浩大,可以参考的书籍又不是很多,因此很多刚学习FFMPEG的人常常感觉到无从下手。 在此我把自己做项目过程中实现的一个非常简单的音频播放器(大约100行代码)源代码传上来,以作备忘,同...

ffmpeg入门小结(二)——音视频同步

1.H264格式简介(视频解码同步相关) ---------------------- 前言 -----------------------     H264是新一代的编码标准,以高压缩高质量和支持多...

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

Qt5学习笔记(9)——控件button使用的一些心得

在最近学习中,使用了QToolButton:顾名思义,就是工具操作相关的按钮。其是一种快速访问按钮命令或选项。所以通常和QToolBar搭配使用。工具按钮通常不显示文本,而显示图标QIcon。其主要搭...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:ffmpeg播放视频音频(ffmpeg 3.0之前老版本)
举报原因:
原因补充:

(最多只允许输入30个字)