使用编译命令:
gcc -o tutorial01 tutorial01.c -lavutil -lavformat -lavcodec -lswscale
源程序如下:
#include
#include
#include
#include
#define debug() fprintf(stderr,"%s#%i\n",__func__,__LINE__)
static struct SwsContext *img_convert_ctx;
void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame)
{
FILE *pFile;
char szFilename[32];
int y;
sprintf(szFilename, "frame%d.ppm", iFrame);
pFile = fopen(szFilename, "wb");
if (pFile == NULL) {
return;
}
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);
}
int main(int argc, char *argv[])
{
AVFormatContext *pFormatCtx;
int i, videoStream;
AVCodecContext *pCodecCtx;
AVCodec *pCodec;
AVFrame *pFrame;
AVFrame *pFrameRGB;
AVPacket packet;
int frameFinished;
int numBytes;
uint8_t *buffer;
if (argc < 2) {
printf("Please provide a movie file\n");
return -1;
}
fprintf(stderr,"ARG OK.\n");
debug();
av_register_all();
fprintf(stderr,"av_register_all() OK.\n");
debug();
pFormatCtx = avformat_alloc_context(); // 分配空间
fprintf(stderr,"avformat_alloc_context() OK.\n");
debug();
if (av_open_input_file(&pFormatCtx, argv[1], NULL, 0, NULL) != 0) {
//if (avformat_open_input(&pFormatCtx, argv[1], NULL, NULL) != 0) { // 打开输入文件
return -1;
}
fprintf(stderr,"avformat_open_input() OK.\n");
debug();
if (av_find_stream_info(pFormatCtx) < 0) {
return -1;
}
fprintf(stderr,"av_find_stream_info() OK.\n");
debug();
dump_format(pFormatCtx, 0, argv[1], 0);
fprintf(stderr,"dump_format() OK.\n");
debug();
videoStream = -1;
for(i=0; inb_streams; i++) {
if (pFormatCtx->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO) {
videoStream = i;
break;
}
}
fprintf(stderr,"find CODEC_TYPE_VIDEO OK.\n");
debug();
if(videoStream == -1) {
return -1;
}
debug();
pCodecCtx=pFormatCtx->streams[videoStream]->codec;
img_convert_ctx = sws_getContext(
pCodecCtx->width,
pCodecCtx->height,
pCodecCtx->pix_fmt,
pCodecCtx->width,
pCodecCtx->height,
PIX_FMT_RGB24,
SWS_BICUBIC,
NULL, NULL, NULL);
fprintf(stderr,"sws_getContext() OK.\n");
debug();
pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
if (pCodec == NULL) {
fprintf(stderr, "Unsupported codec!\n");
return -1;
}
fprintf(stderr,"avcodec_find_decoder() OK.\n");
debug();
if (avcodec_open(pCodecCtx, pCodec) < 0) {
return -1;
}
fprintf(stderr,"avcodec_open() OK.\n");
debug();
pFrame = avcodec_alloc_frame();
fprintf(stderr,"avcodec_alloc_frame() OK.\n");
debug();
pFrameRGB = avcodec_alloc_frame();
if (pFrameRGB == NULL) {
return -1;
}
fprintf(stderr,"avcodec_alloc_frame() OK.\n");
debug();
numBytes = avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width,
pCodecCtx->height);
fprintf(stderr,"avpicture_get_size() OK.\n");
debug();
buffer = (uint8_t *)av_malloc(numBytes*sizeof(uint8_t));
debug();
avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,
pCodecCtx->width, pCodecCtx->height);
fprintf(stderr,"avpicture_fill() OK.\n");
debug(); i = 0;
while(av_read_frame(pFormatCtx, &packet) >= 0) {
if (packet.stream_index == videoStream) {
avcodec_decode_video(pCodecCtx, pFrame,
&frameFinished,
packet.data,
packet.size);
if(frameFinished) {
sws_scale(img_convert_ctx,
(const uint8_t **)pFrame->data,
pFrame->linesize, 0,
pCodecCtx->height,
pFrameRGB->data,
pFrameRGB->linesize);
if (++i <= 5) {
SaveFrame(pFrameRGB, pCodecCtx->width,pCodecCtx->height,i);
}
}
}
av_free_packet(&packet);
}
debug();
av_free(buffer);
av_free(pFrameRGB);
av_free(pFrame);
avcodec_close(pCodecCtx);
av_close_input_file(pFormatCtx);
return 0;
}
阅读(2187) | 评论(0) | 转发(1) |