// 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#include #include #include 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; }
编译:
gcc demo.c -o demo -lavformat -lavcodec -lswscale -lavutil -lz -lm