赞
踩
printf("-------------------\n");
FILE *pFile;
char szFilename[32];
int y;
// Open file
sprintf(szFilename, "frame%d.ppm", iFrame);
pFile=fopen(szFilename, "wb");
if(pFile==NULL)
{
return ;
}
printf("P6\n%d %d\n255\n", width, height);
fprintf(pFile, "P6\n%d %d\n255\n", width, height);
for(y=0; y<height; y++)
{
fwrite(pFrame->data[0]+y*pFrame->linesize[0], 1,width*3 , pFile);
}}
fclose(pFile);
//注册所有类型
av_register_all();
avformat_network_init();
AVFormatContext *pformat;
AVCodecContext *pcodec;
AVCodec *pcc;
//
if(argc<2)
{
printf("please input filename !!!\n");return -1;
}
//为pformat结构申请空间 打开文件
pformat=avformat_alloc_context();
if(avformat_open_input(&pformat,argv[1],NULL,NULL))
{
printf("avformat_open_input error!!!\n");return -1;
}
//查找输入文件信息
if(avformat_find_stream_info(pformat,NULL) < 0)
{
printf("avformat_find_stream_info error !!!\n");return -1;
}
//查找视频流
int videoindex=-1;
int i;
for(i=0;i<pformat->nb_streams;i++)
{
if(pformat->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO){
videoindex=i;break;
}
}
if(videoindex==-1)
{
printf("can't find video stream in %s\n",pformat->filename);return -1;
}
//AVFormatContext ->AVStream ->AVCodecContext
pcodec=pformat->streams[videoindex]->codec;
printf(" find video stream in %s\n",pformat->filename);
//查找该视频流对应的解码器AVCodec
pcc=avcodec_find_decoder(pcodec->codec_id);
//
if(pcc==NULL)
{
printf("cann't find decoder in %s\n",pformat->filename);return -1;
}
//用该解码器打开该视频文件
if(avcodec_open2(pcodec,pcc,NULL)<0)
{
printf("avcodec_open2 error !!!\n");return -1;
}
//AVFrame 是存储视频数据的结构
//pframe 是从数据包中读出来的数据放在其中
//pframeRGB 是通过 sws_scale转化格式之后所要储存的数据结构
AVFrame *pframe,*pframeRGB;
//为pframe 开辟内存空间
pframe=avcodec_alloc_frame();
//为转化视频格式之后的结构开辟内存空间
pframeRGB=avcodec_alloc_frame();
if(pframeRGB==NULL)
{
printf("pframeRGB alloc error !!!\n");return -1;
}
//申请空间 通过得到PIX_FMT_RGB24的一个像素所占用的内存(avpicture_get_size())
uint8_t *out_buffer=(uint8_t *)av_malloc(avpicture_get_size(PIX_FMT_RGB24, pcodec->width, pcodec->height));
//将out_buffer 以pframeRGB的形式关联起来
avpicture_fill((AVPicture *)pframeRGB, out_buffer, PIX_FMT_RGB24, pcodec->width, pcodec->height);
struct SwsContext *sws;
//转换上下文
sws = sws_getContext(pcodec->width, pcodec->height, pcodec->pix_fmt,320,240, PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);
int j=0;
AVPacket *ppacket;//cann*t init
int got_picture;
while(av_read_frame(pformat,ppacket)>=0)
{
if(ppacket->stream_index==videoindex){
int ret=avcodec_decode_video2(pcodec, pframe,&got_picture,ppacket);if(ret < 0){
printf("Decode Error.(解码错误)\n");return -1;
}
if(got_picture){//提取i帧if(pframe->pict_type == AV_PICTURE_TYPE_I){sws_scale(sws , (const uint8_t* const*)pframe->data, pframe->linesize,0, pcodec->height, pframeRGB->data, pframeRGB->linesize);printf("AV_PICTURE_TYPE_I\n");SaveFrame(pframeRGB, 320,240, j);j++;sleep(1);}//提取p帧/* if(pframe->pict_type == AV_PICTURE_TYPE_P){
sws_scale(sws , (const uint8_t* const*)pframe->data, pframe->linesize,0, pcodec->height, pframeRGB->data, pframeRGB->linesize);printf("AV_PICTURE_TYPE_P\n");SaveFrame(pframeRGB, 320,240, j);j++;sleep(1);
}//提取b帧if(pframe->pict_type == AV_PICTURE_TYPE_B){
sws_scale(sws , (const uint8_t* const*)pframe->data, pframe->linesize,0, pcodec->height, pframeRGB->data, pframeRGB->linesize);printf("AV_PICTURE_TYPE_B\n");SaveFrame(pframeRGB, 320,240, j);j++;sleep(1);
}
}*/}
}
av_free_packet(ppacket);
return 0;
}
编译选项:
gcc demux_decode2.c -omain -I/home/fengfei/ffmpeg_Bin/include -L/home/fengfei/ffmpeg_Bin/lib -lavformat -lavdevice -lavcodec -lavutil -lpthread
-lswscale -lswresample -lSDL -lbz2 -lz -lm -lrt
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。