新版本ffmpeg在Visual Studio中的使用。
来源:互联网 发布:mysql远程客户端中文版 编辑:程序博客网 时间:2024/05/21 06:57
FFMpeg是跨平台的开源软件,但是由于采用C99语法,在Visual Studio中无法编译,对于想要使用ffmpeg而不想去配置MinGw和其他依赖库的同学,提供以下方案。
首先去:http://ffmpeg.zeranoe.com/builds/此网站有ffmpeg 编译好的相关文件。此处下载ffmpeg动态链接库,32-bit build(shard),其中包括了所有的动态库,同时也包括了ffmpeg.exe(可以直接做视频转化,参数很强大),ffplay.exe(直接播放音视频)。此处需要用到其中的动态库用于在应用程序中使用,同时DLL需要lib导出,也需要相应的头文件,这个需要下载32 bit build(dev),其中包含了lib,和相应的头文件,但是却没有dll文件,所以需要用到前面的shared库。
好了,准备工作都做好了,就是编码测试了,我写了个简单的测试工程。ffmpeg.c太过复杂了,4000多行代码,而且在visual studio中根本编译不过。
代码如下:
#include <inttypes.h>#include <stdint.h>#include <stdio.h>#ifdef __cplusplusextern "C" {#include "libavutil/avutil.h"#include "libavcodec/avcodec.h"#include "libavformat/avformat.h"#include "libavdevice/avdevice.h"#include "libswscale/swscale.h"}#endif#pragma comment(lib,"avutil.lib")#pragma comment(lib,"avcodec.lib")#pragma comment(lib,"avformat.lib")#pragma comment(lib,"swscale.lib")#include <windows.h>void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame);int img_convert2(AVPicture *dst, int dst_pix_fmt,AVPicture *src, int src_pix_fmt,int src_width, int src_height);int main(int argc, char* argv[]){ av_register_all(); AVFormatContext *pFormatCtx = NULL; // Open video file AVInputFormat *pInputFormat = NULL; if (avformat_open_input(&pFormatCtx, argv[1], NULL, NULL)!=0) { return -1; // Couldn't open file } if(av_find_stream_info(pFormatCtx)<0) { return -1; // Couldn't find stream information } int i = 0; int videoStream=-1; AVCodecContext *pCodecCtx = NULL; for(i=0; i < pFormatCtx->nb_streams; i++) { if(pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_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; AVCodec *pCodec = NULL; // 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 } AVFrame *pFrame,*pFrameRGB; // Allocate video frame pFrame=avcodec_alloc_frame(); pFrameRGB=avcodec_alloc_frame(); if(pFrameRGB==NULL) { return -1; } uint8_t *buffer; int numBytes; // 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)); avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,pCodecCtx->width, pCodecCtx->height); int frameFinished; AVPacket packet; 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 img_convert2((AVPicture *)pFrameRGB,PIX_FMT_RGB24,(AVPicture*)pFrame, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height); // Save the frame to disk if(++i<=100) SaveFrame(pFrameRGB, pCodecCtx->width,pCodecCtx->height, i); } } // Free the packet that was allocated by av_read_frame av_free_packet(&packet); } // Free the RGB image av_free(buffer); av_free(pFrameRGB); // Free the YUV frame av_free(pFrame); // Close the codec avcodec_close(pCodecCtx); av_close_input_file(pFormatCtx); return 0;}int img_convert2(AVPicture *dst, int dst_pix_fmt, AVPicture *src, int src_pix_fmt, int src_width, int src_height){ int w; int h; SwsContext *pSwsCtx; w = src_width; h = src_height; pSwsCtx = sws_getContext(w, h, PIX_FMT_YUV420P, w, h, PIX_FMT_RGB24,SWS_BICUBIC, NULL, NULL, NULL); sws_scale(pSwsCtx,src->data, src->linesize,0, h, dst->data, dst->linesize); SaveFrame((AVFrame *)dst, src_width, src_height, 0); sws_freeContext(pSwsCtx); return 0;}void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame){ FILE *pFile; char szFilename[32]; int y; // Open file sprintf(szFilename, "frame%d.ppm", iFrame); pFile=fopen(szFilename, "wb"); //构造文件头 BITMAPFILEHEADER bmpFileHeader; memset(&bmpFileHeader, 0, sizeof(BITMAPFILEHEADER)); bmpFileHeader.bfType= 0x4D42; bmpFileHeader.bfOffBits= 54; bmpFileHeader.bfSize= 54 + width * height * 24/8; BITMAPINFOHEADER bmpInfoHeader; memset(&bmpInfoHeader, 0, sizeof(BITMAPINFOHEADER)); bmpInfoHeader.biCompression= BI_RGB; bmpInfoHeader.biSize= sizeof(BITMAPINFOHEADER); bmpInfoHeader.biPlanes= 1; bmpInfoHeader.biBitCount= 24;//定死为24位图 bmpInfoHeader.biWidth= width; bmpInfoHeader.biHeight= height; fwrite(&bmpFileHeader, sizeof(bmpFileHeader), 1, pFile); fwrite(&bmpInfoHeader, sizeof(bmpInfoHeader), 1, pFile); // Write pixel data for(y=0; y<height; y++) { fwrite(pFrame->data[0]+y*pFrame->linesize[0], 1, width*3, pFile); } fclose(pFile);}
此代码完成了视频的解码并将原始YUV数据转化为RGB存储到bmp文件中,但此处没做处理,bmp文件图像是反的。
注意一点:ffmpeg头文件需要依赖一些visual studio的头文件,我将自己的测试工程上传到资源中了。
此为完整可编译的ffmpeg vs测试工程。
- 新版本ffmpeg在Visual Studio中的使用。
- 在Visual Studio 2010[VC++]中使用ffmpeg类库
- 在Visual Studio 2010[VC++]中使用ffmpeg类库
- 在Visual Studio 2010[VC++]中使用ffmpeg类库
- 在Visual Studio 2010[VC++]中使用ffmpeg类库
- 在Visual Studio 2010[VC++]中使用ffmpeg类库
- Cplex 在Visual studio 中的使用配置
- 配置visual studio中的ffmpeg开发环境
- 在visual studio 2010中调用ffmpeg
- 在visual studio 2010中调用ffmpeg
- 【FFMPEG】Windows下使用Visual Studio 2010编译ffmpeg全过程
- Tesseract(tesseract-ocr)在Visual Studio 2013中的使用
- Tesseract-ocr在Visual Studio 2013中的使用
- FFmpeg在Visual Studio环境下的编译问题
- 在Visual Studio中编写基于ffmpeg的helloworld程序
- Windows下使用Visual Studio 2010 编译ffmpeg全过程
- Windows下使用Visual Studio 2010 编译ffmpeg全过程
- Windows下使用Visual Studio 2010编译ffmpeg全过程
- Android中View(视图)绘制不同状态背景图片原理深入分析以及StateListDrawable使用详解
- Java JRadioButton ButtonGroup
- Selenium 中 getEval 和runScript 的区别
- 通过GetCurrentObject和GetObject获取和hdc相关的位图对象数据区起始地址
- yum命令的用法
- 新版本ffmpeg在Visual Studio中的使用。
- VC++ 线程同步 CRITICAL_SECTION
- FRM-40212:Invalid Value For Field Ordered_Item_Dsp
- android中Paint类参数介绍
- ubuntu下面安装samba服务器,windows直接可读可写
- 约瑟夫问题的链表解法
- 一个简单的打电话程序
- 杭电2016 数据的交换输出
- 芯片无忧 V1.5(ChipEasy)U盘固态硬盘检测工具 量产必备