利用FFMpeg对视频截图

// tutorial01.c

// Code based on a tutorial by Martin Bohme ([email protected])

// Tested on Gentoo, CVS version 5/01/07 compiled with GCC 4.1.1

 

// A small sample program that shows how to use libavformat and libavcodec to

// read video from a file.

//

// Use

//

// gcc -o tutorial01 tutorial01.c -lavformat -lavcodec -lz

//

// to build (assuming libavformat and libavcodec are correctly installed

// your system).

//

// Run using

//

// tutorial01 myvideofile.mpg

//

// to write the first five frames from "myvideofile.mpg" to disk in PPM

// format.

 

#include <libavcodec/avcodec.h>

#include <libavformat/avformat.h>

#include <libswscale/swscale.h>

 

#include <stdio.h>

static const char* file = "/home/cmzx3444/a.rmvb";

 

void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame)

{

FILE *pFile;

char szFilename[32];

int y;

 

// Open file

sprintf(szFilename, "/home/cmzx3444/a%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[])

{

AVFormatContext *pFormatCtx;

int i, videoStream;

AVCodecContext *pCodecCtx;

AVCodec *pCodec;

AVFrame *pFrame;

AVFrame *pFrameRGB;

AVPacket packet;

int frameFinished;

int numBytes;

uint8_t *buffer;

// Register all formats and codecs

av_register_all();

 

// Open video file

if (av_open_input_file(&pFormatCtx, file, NULL, 0, NULL) != 0)

return -1; // Couldn't open file

// Retrieve stream information

if (av_find_stream_info(pFormatCtx) < 0)

return -1; // Couldn't find stream information

 

// Dump information about file onto standard error

dump_format(pFormatCtx, 0, file, 0);

 

// Find the first video stream

videoStream = -1;

for (i = 0; i < pFormatCtx->nb_streams; i++)

if (pFormatCtx->streams[i]->codec->codec_type == CODEC_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)

{

fprintf(stderr, "Unsupported codec!/n");

return -1; // Codec not found

}

// Open codec

if (avcodec_open(pCodecCtx, pCodec) < 0)

return -1; // Could not open codec

 

// 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 = (uint8_t *) av_malloc(numBytes * sizeof(uint8_t));

 

// Assign appropriate parts of buffer to image planes in pFrameRGB

// Note that pFrameRGB is an AVFrame, but AVFrame is a superset

// of AVPicture

avpicture_fill((AVPicture *) pFrameRGB, buffer, PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);

struct SwsContext *swsContext;

swsContext = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width,

pCodecCtx->height, PIX_FMT_BGR24, SWS_BICUBIC, NULL, NULL, NULL);

 

// Read frames and save first five frames to disk

i = 0;

while (av_read_frame(pFormatCtx, &packet) >= 0)

{

// Is this a packet from the video stream?

if (packet.stream_index == videoStream)

{

// Decode video frame

avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);

// Did we get a video frame?

if (frameFinished)

{

// Convert the image from its native format to RGB

sws_scale(swsContext, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data,

pFrameRGB->linesize);

 

// Save the frame to disk

if (++i <= 5002 && i > 5000)

{

// fprintf(stderr, "保存图片%d/n", i);

SaveFrame(pFrameRGB, pCodecCtx->width, pCodecCtx->height, i);

}

}

}

// Free the packet that was allocated by av_read_frame

av_free_packet(&packet);

}

fprintf(stderr, "中暑:%d/n", i);

// Free the RGB image

av_free(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;

}

你可能感兴趣的:(Stream,video,File,null,buffer,Codec)