在CB2010中调用ffmpeg(3)
1 ffmpeg 新老接口问题及对照集锦
网上很多关于ffmpeg (libav)的资料都是N年以前的,而事实上ffmpeg数年来一直在“以时俱进”,因此无论是一些新手,或者号称为老手的人,有时候难免出头痛。。。。。。
为了解决大家的头痛的问题,特列一个贴子,把ffmpeg相关的一些常见的、版本的问题列举出来,供大家参考,同时也请大家一起补充。
1) 不认识guess_format.
解决: #defineguess_format av_guess_format
接口不变。
2) 不认识av_alloc_format_context
解决: #define av_alloc_format_context avformat_alloc_output_context
接口调整。
3) 不认识CODEC_TYPE_VIDEO 和 CODEC_TYPE_AUDIO
解决:
#defineCODEC_TYPE_VIDEO AVMEDIA_TYPE_VIDEO
#defineCODEC_TYPE_AUDIO AVMEDIA_TYPE_AUDIO
4) 不认识audio_resample_init
解决:#defineaudio_resample_init av_audio_resample_init
接口调整。
5)avcodec_decode_video 到avcodec_decode_video2接口调整
旧代码:
[cpp] view plaincopy
1. len = avcodec_decode_video(c, (short *)outbuf, &out_size, inbuf_ptr, size);
新代码:
[cpp] view plaincopy
1. av_init_packet(&pkt);
2. pkt.data = (unsigned char*)inbuf_ptr;
3. pkt.size = size;
4. len = avcodec_decode_video2(c, &tmpFrame, &got_picture, &pkt);
6) img_convert()找不到
新接口为sws_getContext(), sws_scale()
旧代码
[cpp] view plaincopy
1. img_convert ( (AVPicture *)frameRGB, PIX_FMT_RGB24, (AVPicture*)frame,is->video_st->codec->pix_fmt, is->video_st->codec->width, is->video_st->codec->height);
新代码
[cpp] view plaincopy
1. static struct SwsContext *img_convert_ctx;
2. img_convert_ctx = sws_getContext (is->video_st->codec->width,
3. is->video_st->codec->height, is->video_st->codec->pix_fmt,
4. is->video_st->codec->width, is->video_st->codec->height,
5. PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);
6. sws_scale (img_convert_ctx, frame->data, frame->linesize,0, is->video_st->codec->height, frameRGB->data, frameRGB->linesize);
av_set_parameters老是通不过。
1.1 另一些常见问题(For VC)
在VS2008中,会出现问题及其解决方式:
fatal error C1083: 无法打开包括文件:“inttypes.h”: No such file or directory
在vs2008下没有这个文件,实际上这个文件无非也就是一些整形定义而已,可以直接注释掉这个包含,自己创建这个文件,放到inclue/libavutil下,include改为#include "libavutil/inttypes.h"
fatal error C1083: 无法打开包括文件:“stdint.h”: No such file or directory
copy C:/MSYS/include下的stdint.h到libavutil中。修改#include <stdint.h>为#include “stdint.h”
fatal error C1083: 无法打开包括文件:“libavdevice/avdevice.h”: No such file or directory
用不着,直接注释
ffplay.cpp中报错
fatal error C1083: 无法打开包括文件:“libavcodec/audioconvert.h”: No such file or directory
fatal error C1083: 无法打开包括文件:“libavcodec/colorspace.h”: No such file or directory
make install安装的头文件不全,从libavcodec中copy这两个头文件
fatal error C1083: 无法打开包括文件:“unistd.h”: No such file or directory
许多在Linux下开发的C程序都需要头文件unistd.h,但VC中没有个头文件,
所以用VC编译总是报错。把下面的内容保存为unistd.h,可以解决这个问题。
/** This file is part of the Mingw32 package.
* unistd.hmaps (roughly) to io.h
*/
#ifndef _UNISTD_H
#define _UNISTD_H
#include <io.h>
#include <process.h>
#endif /* _UNISTD_H */
提示
static int wanted_stream[AVMEDIA_TYPE_NB]={
[AVMEDIA_TYPE_AUDIO]=-1,
[AVMEDIA_TYPE_VIDEO]=-1,
[AVMEDIA_TYPE_SUBTITLE]=-1,
};语法错误
VC的标准C++不支持这个赋值方式,我们改为
static int wanted_stream[AVMEDIA_TYPE_NB]=
{
-1,
-1,
0,
-1,
0
};
error C3861: “rint”: 找不到标识符
rint函数是个四舍五入的方法,我们自己实现
inline long rint(double x)
{
if(x >= 0.)
return (long)(x + 0.5);
else
return (long)(x - 0.5);
}
指示FFTSample data[2][2*nb_freq];表达式错误
我们知道标准C++不支持动态数组。修改为
FFTSample *data[2];
data[1]= malloc(sizeof(FFTSample) * 2*nb_freq);
data[0]= malloc(sizeof(FFTSample) * 2*nb_freq);
最后释放
free(data[0]);
free(data[1]);
error C3861: “usleep”: 找不到标识符
VC中没有usleep,usleep是微妙级别的,所以需要把代码改为
usleep(is->audio_st && is->show_audio ? rdftspeed*1000: 5000);
to
Sleep (is->audio_st && is->show_audio ? rdftspeed*1: 5);
指出 ap->time_base= (AVRational){1, 25};语法错误。
还是标准C++不支持这种语法,修改为
ap->time_base.num = 1;
ap->time_base.den = 25;
error C2054: 在“inline”之后应输入“(”
这是因为c不支持inline,我们把cmdutils.c改为cmdutils.cpp,把ffplay.c改为ffplay.cpp。
链接错误:
现在编译可以通过,但是现实一大堆库没有链接(好像有77个链接错误),把
avcodec-52.lib
avformat-52.lib
avutil-50.lib
swscale-0.lib
加进去还是没用,发现是我们用了ffplay.cpp,需要在ffmpeg所有头文件中加。
#ifdef __cplusplus
extern "C" {
#endif
…
#ifdef __cplusplus
}
#endif
这样就可以正确链接了。
以后碰到问题的时候来查一下。