利用FFmpeg将视频文件生成bmp图像帧
2015-08-11 12:55
375 查看
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <windows.h> #include "avformat.h" #include "avcodec.h" #include "swscale.h" #pragma comment (lib, "avcodec.lib") #pragma comment (lib, "avformat.lib") #pragma comment (lib, "avutil.lib") #pragma comment (lib, "swscale.lib") #ifndef _WINGDI_ #define _WINGDI_ typedef struct tagBITMAPFILEHEADER { WORD bfType; DWORD bfSize; WORD bfReserved1; WORD bfReserved2; DWORD bfOffBits; } BITMAPFILEHEADER, FAR *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER; typedef struct tagBITMAPINFOHEADER{ DWORD biSize; LONG biWidth; LONG biHeight; WORD biPlanes; WORD biBitCount; DWORD biCompression; DWORD biSizeImage; LONG biXPelsPerMeter; LONG biYPelsPerMeter; DWORD biClrUsed; DWORD biClrImportant; } BITMAPINFOHEADER, FAR *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER; #endif void SaveAsBMP (AVFrame *pFrameRGB, int width, int height, int index, int bpp) { char buf[5] = {0}; BITMAPFILEHEADER bmpheader; BITMAPINFOHEADER bmpinfo; FILE *fp; char filename[20] = "R:\\test"; _itoa (index, buf, 10); strcat (filename, buf); strcat (filename, ".bmp"); if ( (fp=fopen(filename,"wb+")) == NULL ) { printf ("open file failed!\n"); return; } bmpheader.bfType = 0x4d42; bmpheader.bfReserved1 = 0; bmpheader.bfReserved2 = 0; bmpheader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); bmpheader.bfSize = bmpheader.bfOffBits + width*height*bpp/8; bmpinfo.biSize = sizeof(BITMAPINFOHEADER); bmpinfo.biWidth = width; bmpinfo.biHeight = height; bmpinfo.biPlanes = 1; bmpinfo.biBitCount = bpp; bmpinfo.biCompression = BI_RGB; bmpinfo.biSizeImage = (width*bpp+31)/32*4*height; bmpinfo.biXPelsPerMeter = 100; bmpinfo.biYPelsPerMeter = 100; bmpinfo.biClrUsed = 0; bmpinfo.biClrImportant = 0; fwrite (&bmpheader, sizeof(bmpheader), 1, fp); fwrite (&bmpinfo, sizeof(bmpinfo), 1, fp); fwrite (pFrameRGB->data[0], width*height*bpp/8, 1, fp); fclose(fp); } int main (void) { unsigned int i = 0, videoStream = -1; AVCodecContext *pCodecCtx; AVFormatContext *pFormatCtx; AVCodec *pCodec; AVFrame *pFrame, *pFrameRGB; struct SwsContext *pSwsCtx; const char *filename = "test.avi"; AVPacket packet; int frameFinished; int PictureSize; uint8_t *buf; av_register_all(); if ( av_open_input_file(&pFormatCtx, filename, NULL, 0, NULL) != 0 ) { printf ("av open input file failed!\n"); exit (1); } if ( av_find_stream_info(pFormatCtx) < 0 ) { printf ("av find stream info failed!\n"); exit (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) { printf ("find video stream failed!\n"); exit (1); } pCodecCtx = pFormatCtx->streams[videoStream]->codec; pCodec = avcodec_find_decoder (pCodecCtx->codec_id); if (pCodec == NULL) { printf ("avcode find decoder failed!\n"); exit (1); } if ( avcodec_open(pCodecCtx, pCodec)<0 ) { printf ("avcode open failed!\n"); exit (1); } pFrame = avcodec_alloc_frame(); pFrameRGB = avcodec_alloc_frame(); if ( (pFrame==NULL)||(pFrameRGB==NULL) ) { printf("avcodec alloc frame failed!\n"); exit (1); } PictureSize = avpicture_get_size (PIX_FMT_BGR24, pCodecCtx->width, pCodecCtx->height); buf = av_malloc(PictureSize); if ( buf == NULL ) { printf( "av malloc failed!\n"); exit(1); } avpicture_fill ( (AVPicture *)pFrameRGB, buf, PIX_FMT_BGR24, pCodecCtx->width, pCodecCtx->height); pSwsCtx = sws_getContext (pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, PIX_FMT_BGR24, SWS_BICUBIC, NULL, NULL, NULL); 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) { //反转图像 //*(pFrame->data[0]) = pCodecCtx->width * (pCodecCtx->height-1); //pFrame ->linesize[0] = -(pCodecCtx->height); pFrame->data[0] += pFrame->linesize[0] * (pCodecCtx->height - 1); pFrame->linesize[0] *= -1; pFrame->data[1] += pFrame->linesize[1] * (pCodecCtx->height / 2 - 1); pFrame->linesize[1] *= -1; pFrame->data[2] += pFrame->linesize[2] * (pCodecCtx->height / 2 - 1); pFrame->linesize[2] *= -1; sws_scale (pSwsCtx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize); SaveAsBMP (pFrameRGB, pCodecCtx->width, pCodecCtx->height, i++, 24); } } av_free_packet(&packet); } sws_freeContext (pSwsCtx); av_free (pFrame); av_free (pFrameRGB); avcodec_close (pCodecCtx); av_close_input_file (pFormatCtx); return 0; }
相关文章推荐
- HDU 1421(搬寝室)动态规划
- 黑马程序员——24,File类,Properties类,
- 【原创】驱动枚举之EnumServicesStatusEx
- Java操作xml文件的心得
- AFNetworking 取消请求
- Android 调用百度地图所需权限
- lua的string.gsub初使用
- Spring—Hibernate
- 【转】多去阅读思维训练类的书籍
- 基于Zend framework的投票系统的实现
- 大约HR升级版的设计为组汇总
- win8.1 Framework3.5安装不上的问题
- NBUT 1580 素数分解dp
- Go 1.5关键字搜索目录、文件、文件内容_修复一个小BUG
- 不记录history及清除history
- STL中成员类型的作用
- Ajax load方式传值
- Oracle创建表空间、创建用户以及授权、查看权限
- 更新一下缺省源
- CodeForces 569A-Music