代码,将FLV中的视频的每一帧保存成PPM文件
-
#define __STDC_CONSTANT_MACROS
-
extern "C" {
-
#include <avcodec.h>
-
#include <avformat.h>
-
#include <swscale.h>
-
}
-
-
#include <stdio.h>
-
-
void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame)
-
{
-
FILE *pFile;
-
char szFilename[32];
-
int y;
-
-
// Open file
-
sprintf(szFilename, "frame%d.ppm", iFrame);
-
pFile=fopen(szFilename, "wb");
-
if(pFile==NULL)
-
return;
-
-
// Write header
-
fprintf(pFile, "P6\n%d %d\n255\n", width, height);
-
-
// Write pixel data
-
for(y=0; y<height; y++)
-
fwrite(pFrame->data[0]+y*pFrame->linesize[0], 1, width*3, pFile);
-
-
// Close file
-
fclose(pFile);
-
}
-
-
int main(int argc, char *argv[])
-
{
-
static AVFormatContext *pFormatCtx;
-
int i, videoStream;
-
AVCodecContext *pCodecCtx;
-
AVCodec *pCodec;
-
AVFrame *pFrame;
-
AVFrame *pFrameRGB;
-
AVPacket packet;
-
int frameFinished;
-
int numBytes;
-
uint8_t *buffer;
-
AVDictionary * options;
-
// Register all formats and codecs
-
av_register_all();
-
-
// Open video file
-
if(avformat_open_input(&pFormatCtx, argv[1], NULL, NULL)!=0)
-
return -1; // Couldn't open file
-
-
// Retrieve stream information
-
if(avformat_find_stream_info(pFormatCtx,NULL)<0)
-
return -1; // Couldn't find stream information
-
-
// Dump information about file onto standard error
-
av_dump_format(pFormatCtx, 0, argv[1], false);
-
-
// Find the first video stream
-
videoStream=-1;
-
for(i=0; i<pFormatCtx->nb_streams; i++)
-
if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO)
-
{
-
videoStream=i;
-
break;
-
}
-
if(videoStream==-1)
-
return -1; // Didn't find a video stream
-
-
// Get a pointer to the codec context for the video stream
-
pCodecCtx=pFormatCtx->streams[videoStream]->codec;
-
-
// Find the decoder for the video stream
-
pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
-
if(pCodec==NULL)
-
return -1; // Codec not found
-
-
// Open codec
-
if(avcodec_open2(pCodecCtx, pCodec,NULL)<0)
-
return -1; // Could not open codec
-
-
// Hack to correct wrong frame rates that seem to be generated by some
-
// codecs
-
// if(pCodecCtx->frame_rate>1000 && pCodecCtx->frame_rate_base==1)
-
// pCodecCtx->frame_rate_base=1000;
-
-
// Allocate video frame
-
pFrame=avcodec_alloc_frame();
-
-
// Allocate an AVFrame structure
-
pFrameRGB=avcodec_alloc_frame();
-
if(pFrameRGB==NULL)
-
return -1;
-
-
// Determine required buffer size and allocate buffer
-
numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width,
-
pCodecCtx->height);
-
buffer=new uint8_t[numBytes];
-
-
// Assign appropriate parts of buffer to image planes in pFrameRGB
-
avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,
-
pCodecCtx->width, pCodecCtx->height);
-
-
// Read frames and save first five frames to disk
-
i=0;
-
struct SwsContext *img_convert_ctx = NULL;
-
img_convert_ctx = sws_getContext(pCodecCtx->width,pCodecCtx->height,pFormatCtx->streams[videoStream]->codec->pix_fmt , pCodecCtx->width, pCodecCtx->height, PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);
-
while(av_read_frame(pFormatCtx, &packet)>=0)
-
{
-
// Is this a packet from the video stream?
-
if(packet.stream_index==videoStream)
-
{
-
// Decode video frame
-
frameFinished = 0;
-
int ret = avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished,
-
&packet);
-
if(ret < 0)
-
{
-
av_log(NULL, AV_LOG_ERROR, "Error decoding video\n");
-
break;
-
}
-
if(frameFinished)
-
{
-
sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
-
if(++i<=1000)
-
SaveFrame(pFrameRGB, pCodecCtx->width, pCodecCtx->height, i);
-
}
-
}
-
-
// Free the packet that was allocated by av_read_frame
-
av_free_packet(&packet);
-
}
-
-
// Free the RGB image
-
delete [] buffer;
-
av_free(pFrameRGB);
-
-
// Free the YUV frame
-
av_free(pFrame);
-
-
// Close the codec
-
avcodec_close(pCodecCtx);
-
-
// Close the video file
-
av_close_input_file(pFormatCtx);
-
-
return 0;
-
}
参考:
修改编译错误 __STDC_CONSTANT_MACROS
FFMEG介绍和API用法网站
FFMEG和SDL教程(For 显示)
FFMPEG的图像转化函数swscale介绍
阅读(4528) | 评论(0) | 转发(0) |