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);
};
{
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);
};
相关文章推荐
- NDK开发——FFmpeg实现视频转YUV、视频转RGB显示、音频转PCM、音频播放、音视频同步
- iOS 音视频高级编程:Audio Unit播放FFmpeg解码的音频
- ffmpeg编程基础:视频解码、音频播放
- iOS 音视频开发:Audio Unit播放FFmpeg解码的音频
- ffmpeg学习:ffmpeg下载,播放音频、视频,读取USB摄像头数据流并实时播放
- 基于ffmpeg的 视频解码 音频解码.播放等
- android基于ffmpeg的简单视频播发器 音频播放
- javacv-ffmpeg播放视频里的音频
- iOS 音视频高级编程:Audio Unit播放FFmpeg解码的音频
- FFmpeg——Windows下,视频播放器4:播放音频、音视频同步
- 关于xcode本地,网络的视频,音频不播放
- 音频视频解决方案:GStreamer/ffmpeg/ffdshow/directshow/vfw
- iOS开发系列--音频播放、录音、视频播放、拍照、视频录制
- iOS开发系列--音频播放、录音、视频播放、拍照、视频录制
- iOS开发系列--音频播放、录音、视频播放、拍照、视频录制
- [ffmpeg] 不能正常播放视频,播放窗口绿屏
- VLC播放 RTP流的 音频 视频的 sdp描述文件
- 使用FFmpeg+GDI解码和播放视频
- 音频、视频时间戳计算及每帧播放时间
- 【iOS-Cocos2d游戏开发之十四】音频/音效/视频播放(利用Cocos2D-iPhone-Extensions嵌入Cocos2d进行视频播放!)