参考链接1:Compile LibJPEG
参考链接2:利用ffmpeg0.5 和libjpeg实现抽取视频帧并将其保存为jpeg文件格式程序
参考链接3:ffmpeg 重写tutorial01程序--将一个视频文件解码输出ppm文件或bmp文件
操作系统: windows 7 旗舰版
开发环境:vs2008
相关库:ffmpeg,libjpeg
vs工程文件:
1. 编译libjpeg
以前编译ffmpeg受过伤,想偷个懒,想想这么通用的库,网上提供的的.lib应该很多的,google "libjpeg for windows",第一条就提供了相应的库,大喜,用之,而事实上,正是因为自己的拿来主义,导致我后面遇到了各种莫名奇妙的问题,在执行jpeg_wirte_scanlines()和jpeg_finish_compress()时出现"写入位置发生访问冲突",由于是编译好的lib库,无法单步调试到相关函数里面检查错误,这个问题让人很绝望。

网上google时,无意找到了Compile LibJPEG看看,似乎编译过程也并不复杂,报着最后一丝希望,决定自己编译下libjpeg。该文已经将编译过程写得很详细了,我在windows7下编译也没有任何问题。下面我做一个简单的翻译。
1.1 从 http://www.ijg.org/files/上下载jpegsrc.v6b.tar.gz。
1.2 解压,假设我们放在C:\temp\jpegsrc.v6b下。
1.3 重命名c:\jpegsrc.v6b\jpeg-6b\makefile.vc 为 c:\jpegsrc.v6b\jpeg-6b\Makefile。
1.4 重命名c:\jpegsrc.v6b\jpeg-6b\jconfig.vc 为 c:\jpegsrc.v6b\jpeg-6b\jconfig.h。
1.5 打开cmd(快捷键:win+r)
1.6 在cmd中运行如下命令。vsvars32.bat的位置可能会不同,结合自己情况修改。注意:""不能少
- "C:\Program Files\Microsoft Visual Studio 9.0\Common7\Tools\vsvars32.bat"
- cd C:\temp\jpegsrc.v6b\jpeg-6b
- nmake -f Makefile
1.8 对C:\temp\jpegsrc.v6b\jpeg-6b\jmorecfg.h进行修改:
1.9 对C:\temp\jpegsrc.v6b\jpeg-6b\jmorecfg.h进行修改:
1.10 将
"jconfig.h"
"jerror.h"
"jinclude.h"
"jmorecfg.h"
"jpeglib.h"
"jerror.h"
"jinclude.h"
"jmorecfg.h"
"jpeglib.h"
以及
jpegliblib
添加到你的vs2008工程文件中
2. 使用libjpeg
由于libjpeg是C语言写的,在包含jpeglib.h时需要加上
3. 部分源代码
#include <windows.h>
extern "C"{
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include "jpeglib.h" // for jpeglib
};
//实现视频帧的jpeg压缩
void saveAsJpeg(AVFrame *pFrameRGB, int width, int height, int framenum)
{
char fname[128];
// AVPicture my_pic ;
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
JSAMPROW row_pointer[1];
int row_stride;
uint8_t *buffer;
FILE *fp = NULL;
buffer = pFrameRGB->data[0];
int size = sizeof(buffer);
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
//_snprintf(fname, sizeof(fname), "frames%d.jpg", framenum);
sprintf(fname, "frames%d.jpg", framenum);
fp = fopen(fname, "wb");
if (fp == NULL)
return;
jpeg_stdio_dest(&cinfo, fp);
cinfo.image_width = width;
cinfo.image_height = height;
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, 80, true);
jpeg_start_compress(&cinfo, TRUE);
row_stride = width * 3;
while (cinfo.next_scanline < height)
{
/* jpeg_write_scanlines expects an array of pointers to scanlines.
* Here the array is only one element long, but you could pass
* more than one scanline at a time if that's more convenient.
*/
row_pointer[0] = &buffer[cinfo.next_scanline * row_stride];
jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
jpeg_finish_compress(&cinfo);
fclose(fp);
jpeg_destroy_compress(&cinfo);
printf("compress %d frame finished!\n",framenum) ;
return ;
}
|