Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1501051
  • 博文数量: 218
  • 博客积分: 6394
  • 博客等级: 准将
  • 技术积分: 2563
  • 用 户 组: 普通用户
  • 注册时间: 2008-02-08 15:33
个人简介

持之以恒

文章分类

全部博文(218)

文章存档

2013年(8)

2012年(2)

2011年(21)

2010年(55)

2009年(116)

2008年(16)

分类: C/C++

2013-11-25 16:32:08


代码,将FLV中的视频的每一帧保存成PPM文件

点击(此处)折叠或打开

  1. #define __STDC_CONSTANT_MACROS
  2. extern "C" {
  3. #include <avcodec.h>
  4. #include <avformat.h>
  5. #include <swscale.h>
  6. }

  7. #include <stdio.h>

  8. void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame)
  9. {
  10.     FILE *pFile;
  11.     char szFilename[32];
  12.     int y;

  13.     // Open file
  14.     sprintf(szFilename, "frame%d.ppm", iFrame);
  15.     pFile=fopen(szFilename, "wb");
  16.     if(pFile==NULL)
  17.         return;

  18.     // Write header
  19.     fprintf(pFile, "P6\n%d %d\n255\n", width, height);

  20.     // Write pixel data
  21.     for(y=0; y<height; y++)
  22.         fwrite(pFrame->data[0]+y*pFrame->linesize[0], 1, width*3, pFile);

  23.     // Close file
  24.     fclose(pFile);
  25. }

  26. int main(int argc, char *argv[])
  27. {
  28.     static AVFormatContext *pFormatCtx;
  29.     int i, videoStream;
  30.     AVCodecContext *pCodecCtx;
  31.     AVCodec *pCodec;
  32.     AVFrame *pFrame;
  33.     AVFrame *pFrameRGB;
  34.     AVPacket packet;
  35.     int frameFinished;
  36.     int numBytes;
  37.     uint8_t *buffer;
  38.         AVDictionary * options;
  39.     // Register all formats and codecs
  40.     av_register_all();

  41.     // Open video file
  42.     if(avformat_open_input(&pFormatCtx, argv[1], NULL, NULL)!=0)
  43.         return -1; // Couldn't open file

  44.     // Retrieve stream information
  45.     if(avformat_find_stream_info(pFormatCtx,NULL)<0)
  46.         return -1; // Couldn't find stream information

  47.     // Dump information about file onto standard error
  48.     av_dump_format(pFormatCtx, 0, argv[1], false);

  49.     // Find the first video stream
  50.     videoStream=-1;
  51.     for(i=0; i<pFormatCtx->nb_streams; i++)
  52.         if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO)
  53.         {
  54.             videoStream=i;
  55.             break;
  56.         }
  57.     if(videoStream==-1)
  58.         return -1; // Didn't find a video stream

  59.     // Get a pointer to the codec context for the video stream
  60.     pCodecCtx=pFormatCtx->streams[videoStream]->codec;

  61.     // Find the decoder for the video stream
  62.     pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
  63.     if(pCodec==NULL)
  64.         return -1; // Codec not found

  65.     // Open codec
  66.     if(avcodec_open2(pCodecCtx, pCodec,NULL)<0)
  67.         return -1; // Could not open codec

  68.     // Hack to correct wrong frame rates that seem to be generated by some
  69.     // codecs
  70.     // if(pCodecCtx->frame_rate>1000 && pCodecCtx->frame_rate_base==1)
  71.     // pCodecCtx->frame_rate_base=1000;

  72.     // Allocate video frame
  73.     pFrame=avcodec_alloc_frame();

  74.     // Allocate an AVFrame structure
  75.     pFrameRGB=avcodec_alloc_frame();
  76.     if(pFrameRGB==NULL)
  77.         return -1;

  78.     // Determine required buffer size and allocate buffer
  79.     numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width,
  80.         pCodecCtx->height);
  81.     buffer=new uint8_t[numBytes];

  82.     // Assign appropriate parts of buffer to image planes in pFrameRGB
  83.     avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,
  84.         pCodecCtx->width, pCodecCtx->height);

  85.     // Read frames and save first five frames to disk
  86.     i=0;
  87.     struct SwsContext *img_convert_ctx = NULL;
  88.     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);
  89.     while(av_read_frame(pFormatCtx, &packet)>=0)
  90.     {
  91.         // Is this a packet from the video stream?
  92.         if(packet.stream_index==videoStream)
  93.         {
  94.             // Decode video frame
  95.             frameFinished = 0;
  96.             int ret = avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished,
  97.                 &packet);
  98.             if(ret < 0)
  99.             {
  100.                 av_log(NULL, AV_LOG_ERROR, "Error decoding video\n");
  101.                 break;
  102.             }
  103.             if(frameFinished)
  104.             {
  105.                 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
  106.                 if(++i<=1000)
  107.                     SaveFrame(pFrameRGB, pCodecCtx->width, pCodecCtx->height, i);
  108.             }
  109.         }

  110.         // Free the packet that was allocated by av_read_frame
  111.         av_free_packet(&packet);
  112.     }

  113.     // Free the RGB image
  114.     delete [] buffer;
  115.     av_free(pFrameRGB);

  116.     // Free the YUV frame
  117.     av_free(pFrame);

  118.     // Close the codec
  119.     avcodec_close(pCodecCtx);

  120.     // Close the video file
  121.     av_close_input_file(pFormatCtx);

  122.     return 0;
  123. }
参考:
修改编译错误 __STDC_CONSTANT_MACROS
FFMEG介绍和API用法网站

FFMEG和SDL教程(For 显示)

FFMPEG的图像转化函数swscale介绍
阅读(4528) | 评论(0) | 转发(0) |
0

上一篇:MakeFile学习

下一篇:没有了

给主人留下些什么吧!~~