您的位置:首页 > 其它

ffmpeg播放视频音频

2012-03-29 16:48 369 查看
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);

};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: