windows下ffmpeg编译成lib、dll与使用ffmpeg制作播放器
2012-12-14 10:09
411 查看
自己编译ffmpeg的话比较麻烦的还是,可以参考这篇文章。
windows下使用MinGW+msys编译ffmpeg
http://blog.chinaunix.net/uid-20718335-id-2980793.html
实际上我按照这个流程编译了一遍,有些库不全,虽然编译通过了,最终似乎无法使用。
只好引用了ffmpeg项目组的
FFMPEG SDK,我下载的是当前最新的3.2版本。
点击直接下载
对应的FFmpeg SDK开发手册直接下载。
此外还有一份参考资料:
英文版:An_ffmpeg_and_SDL_Tutorial
中文版:FFmpeg和SDL
下面大致列举一下我遇到的问题,我的操作系统是Windows 7,,64位旗舰版。
其中第八项faad2、第九项faac、第11、12项目amr-nb和amr-wb编译出了一些问题
直接忽视,最后在编译ffmpeg的时候去掉对应项的enable指令就好了。
之后是集成ffmpeg的功能到自己的播放器上,我是基于MFC的对话框做了一个小小的播放器。
这里记录一点点流程,需要全部工程源码的可以私信我。
引用头文件的方法是这样子,不然最后链接的时候会提示出错
这里我把上面步骤里面最后导出的头文件其实是直接放到了一个目录下面,
大家也可以直接在VS的项目属性(配置属性-> VC++目录->包含目录和库目录)里面增加对应的头文件所在目录,
就可以这么直接包含头文件了。
然后是添加静态库lib文件,方法比较多,我是在.cpp文件里面这么弄:
然后是对应的bin文件,也就是导出到 local/bin目录下的一些文件,这里我直接拷贝到了项目exe生成目录里面。
给大家看看我的目录结构,如下图:其中FFmpeg-full-sdk-3.2是最开始的那个SDK解压直接得到的。
![](http://img.my.csdn.net/uploads/201212/14/1355450196_3516.png)
以下的话我直接对ffmpeg的内容进行了封装,生成了一个类CNcMCodec,类的头文件内容如下:
下面是.cpp的内容。
这个代码只有一个很基本的框架,还有一点BUG(设置读取指定位置会出错),
我自己没弄明白是怎么回事。
如果你解决了或者对代码做了优化,希望能够分享给我。
需要VS工程与源代码的:点这里
http://download.csdn.net/detail/luofl1992/5089125
收资源分是希望大家好好利用资源。谢谢。
windows下使用MinGW+msys编译ffmpeg
http://blog.chinaunix.net/uid-20718335-id-2980793.html
实际上我按照这个流程编译了一遍,有些库不全,虽然编译通过了,最终似乎无法使用。
只好引用了ffmpeg项目组的
FFMPEG SDK,我下载的是当前最新的3.2版本。
点击直接下载
对应的FFmpeg SDK开发手册直接下载。
此外还有一份参考资料:
英文版:An_ffmpeg_and_SDL_Tutorial
中文版:FFmpeg和SDL
下面大致列举一下我遇到的问题,我的操作系统是Windows 7,,64位旗舰版。
其中第八项faad2、第九项faac、第11、12项目amr-nb和amr-wb编译出了一些问题
直接忽视,最后在编译ffmpeg的时候去掉对应项的enable指令就好了。
之后是集成ffmpeg的功能到自己的播放器上,我是基于MFC的对话框做了一个小小的播放器。
这里记录一点点流程,需要全部工程源码的可以私信我。
引用头文件的方法是这样子,不然最后链接的时候会提示出错
extern "C" { #ifndef INT64_C #define INT64_C #define UINT64_C #endif #include "avcodec.h" #include "avdevice.h" #include "avfilter.h" #include "avformat.h" #include "avutil.h" #include "swscale.h" }
这里我把上面步骤里面最后导出的头文件其实是直接放到了一个目录下面,
大家也可以直接在VS的项目属性(配置属性-> VC++目录->包含目录和库目录)里面增加对应的头文件所在目录,
就可以这么直接包含头文件了。
然后是添加静态库lib文件,方法比较多,我是在.cpp文件里面这么弄:
#pragma comment(lib, "avcodec.lib") #pragma comment(lib, "avdevice.lib") #pragma comment(lib, "avfilter.lib") #pragma comment(lib, "avformat.lib") #pragma comment(lib, "swscale.lib") #pragma comment(lib, "avutil.lib") #pragma comment(lib, "postproc.lib") #pragma comment(lib, "swresample.lib")
然后是对应的bin文件,也就是导出到 local/bin目录下的一些文件,这里我直接拷贝到了项目exe生成目录里面。
给大家看看我的目录结构,如下图:其中FFmpeg-full-sdk-3.2是最开始的那个SDK解压直接得到的。
![](http://img.my.csdn.net/uploads/201212/14/1355450196_3516.png)
以下的话我直接对ffmpeg的内容进行了封装,生成了一个类CNcMCodec,类的头文件内容如下:
#ifndef _NC_MEDIA_DECODER_H_ #define _NC_MEDIA_DECODER_H_ extern "C" { #if 0 #ifndef INT64_C #define INT64_C #define UINT64_C #endif #include "libavcodec/avcodec.h" #include "libavdevice/avdevice.h" #include "libavfilter/avfilter.h" #include "libavformat/avformat.h" #include "libavutil/avutil.h" #include "libswscale/swscale.h" #else #include "avcodec.h" #include "avdevice.h" #include "avfilter.h" #include "avformat.h" #include "avutil.h" #include "swscale.h" #endif } class CNcMCodec { protected: AVFormatContext *pFormatCtx; AVCodecContext *pCodecCtx; AVCodec *pCodec; int videoStream; AVFrame *pFrame, *pFrameRGB; uint8_t *buffer; DWORD bmfHeaderLen; public: CNcMCodec(void); virtual ~CNcMCodec(void); bool OpenFile(LPCTSTR lpFilePath, BITMAPINFO &bmpInfo); AVPicture * GetNextFrame(); }; #endif // _NC_MEDIA_DECODER_H_
下面是.cpp的内容。
#include "stdafx.h"
#include "NcMCodec.h"
// 用于不同类型字符串的转换,宏T2A、A2T等
#include <atlconv.h>
#pragma comment(lib, "avcodec.lib") #pragma comment(lib, "avdevice.lib") #pragma comment(lib, "avfilter.lib") #pragma comment(lib, "avformat.lib") #pragma comment(lib, "swscale.lib") #pragma comment(lib, "avutil.lib") #pragma comment(lib, "postproc.lib") #pragma comment(lib, "swresample.lib")
static void CodecInit(void)
{
static bool bInitialed(false);
if ( true == bInitialed )
return;
av_register_all();
}
CNcMCodec::CNcMCodec(void)
{
pFormatCtx = NULL;
pCodecCtx = NULL;
CodecInit();
}
CNcMCodec::~CNcMCodec(void)
{
}
bool CNcMCodec::OpenFile(LPCTSTR lpFilePath, BITMAPINFO &bmpInfo)
{
char path[MAX_PATH];
#ifdef _UNICODE
USES_CONVERSION;
strcpy_s<MAX_PATH>( path, T2A(lpFilePath) );
#else
strcpy_s<MAX_PATH>( path, lpFilePath );
#endif
if ( av_open_input_file( &pFormatCtx, path, NULL, 0, NULL ) )
return false; // 文件打开失败
if ( av_find_stream_info(pFormatCtx) < 0 )
return 0; // 无法找到流信息
dump_format( pFormatCtx, 0, path, 0 );
size_t i = 0;
videoStream = -1;
for ( i = 0; i < pFormatCtx->nb_streams; i++ )
{
if ( pFormatCtx->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO )
{
videoStream = i;
break;
}
}
if ( -1 == videoStream )
return false;
pCodecCtx = pFormatCtx->streams[videoStream]->codec;
pCodec = avcodec_find_decoder( pCodecCtx->codec_id );
if ( NULL == pCodec )
return false;
if ( avcodec_open(pCodecCtx, pCodec) < 0 )
return false; // 无法打开解码器
pFrame = avcodec_alloc_frame();
pFrameRGB = avcodec_alloc_frame();
if ( NULL == pFrame )
return false;
int bytes = avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);
buffer = (uint8_t *)av_malloc(bytes * sizeof(uint8_t));
avpicture_fill( (AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height );
// 设置位图信息头数据
BITMAPINFOHEADER &infoHeader(bmpInfo.bmiHeader);
infoHeader.biBitCount = 24;
infoHeader.biClrImportant = 0;
infoHeader.biClrUsed = 0;
infoHeader.biCompression = 0;
infoHeader.biHeight = 0 - pCodecCtx->height; // 这里要是负数,否则在MFC下面使用stretchBlt显示的图像是倒着的
infoHeader.biWidth = pCodecCtx->width;
infoHeader.biPlanes = 1;
infoHeader.biSize = 40;
infoHeader.biSizeImage = 0;
infoHeader.biXPelsPerMeter = 0;
infoHeader.biYPelsPerMeter = 0;
return true;
}
AVPicture * CNcMCodec::GetNextFrame()
{
AVPacket packet;
int frameFinished = 0;
// Convert the image from its native format to RGB
while ( av_read_frame( pFormatCtx, &packet ) >= 0 )
{
if ( videoStream == packet.stream_index )
{
avcodec_decode_video(pCodecCtx, pFrame, &frameFinished, packet.data, packet.size);
}
if ( frameFinished )
{
// img_convert((AVPicture *)pFrameRGB, PIX_FMT_RGB24, (AVPicture *)pFrame, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height );
// 这里不能用那个 turial上的函数,目前的版本上已经没有了这个img_convert函数,需要用下面的三句话来替换
static struct SwsContext *img_convert_ctx;
img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height,PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);
// other codes
// Convert the image from its native format to RGB
sws_scale(img_convert_ctx, (uint8_t **)pFrame->data, pFrame->linesize,
0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
return (AVPicture *)pFrameRGB;
}
}
return NULL;
}
// NcMCodec.cpp至此已经结束
// 至于如何把这个AVPicture结构转换成HBITMAP,用于MFC的显示,
// 我的方法如下,其中dec是上述的一个解码器类对象,使用之前应该先进行dec.OpenFile操作:
HBITMAP CNcMPlayerDlg::GetNextFrame(CDC *pDC, HBITMAP &hBitmap)
{
AVPicture *pFrame = dec.GetNextFrame();
if ( NULL == pFrame )
{
hBitmap = NULL;
return NULL;
}
LPVOID lpDIBBits = (LPVOID)pFrame->data[0];/*(lpBuffer)+((BITMAPFILEHEADER *)lpBuffer)->bfOffBits*/ // 像素的数值
hBitmap = CreateDIBitmap(pDC->m_hDC, &bmpInfo.bmiHeader , CBM_INIT,lpDIBBits, &bmpInfo, DIB_RGB_COLORS);
return hBitmap;
}
这个代码只有一个很基本的框架,还有一点BUG(设置读取指定位置会出错),
我自己没弄明白是怎么回事。
如果你解决了或者对代码做了优化,希望能够分享给我。
需要VS工程与源代码的:点这里
http://download.csdn.net/detail/luofl1992/5089125
收资源分是希望大家好好利用资源。谢谢。
相关文章推荐
- windows下使用ndk-r8e编译libffmpeg.so-1.2.1要点
- ffmpeg编译(生成Windows或Win32平台dll, lib)
- ffmpeg编译(生成Windows或Win32平台dll, lib)
- ffmpeg 编译 dll 和 lib 文件
- windows ffmpeg mingw编译流程及vs中的使用方法(vs2005及其以上可用)
- windows下使用MinGW+msys编译ffmpeg
- windows中LIB和DLL的区别与使用
- windows下使用MinGW+msys编译ffmpeg
- 如何将ffmpeg在windows编译和使用
- windows 下使用 MinGW + msys 编译 ffmpeg
- Windows下编译、移植、使用ffmpeg(编译篇)
- FFMpeg在windows下的编译和使用
- 【FFMEPG】windows下编译ffmpeg2.5——使用VS2013,ARMLINUX,ANDORID编译ffmpeg
- Windows下使用MinGW+msys编译FFmpeg错误
- windows下的编译生成的R.dll 无R.lib 由dll生成lib的方法
- windows下使用MinGW+msys编译ffmpeg
- VC2005编译SQLite,生成WINCE上使用的DLL和Lib
- windows 下使用 MinGW + msys 编译 ffmpeg
- Windows下编译、移植、使用ffmpeg(移植篇)
- VC2005编译SQLite 生成WINCE上使用的DLL和Lib