. 下载配置sdl
. 下载配置ffmpeg sdk
. 下载ffmpeg 源代码
. 拷贝源代码中的ffplay.c, cmdutil.h, cmdutil.c 到新建的VC工程中
编译之~
出现问题
1. #include "version.h" 找不到文件。
注释掉这行,好像没什么用处。
2. _main 重复定义
在ffplay.c文件前面 增加 #define __MINGW32__ (这个应该都想得到,We don't want SDL to override our main() )
3.extern "C"
{
#include "libavutil/avstring.h"
#include "libavformat/avformat.h"
#include "libavformat/rtsp.h"
#include "libavdevice/avdevice.h"
#include "libswscale/swscale.h"
#include "libavcodec/audioconvert.h"
#include "libavcodec/opt.h"
}
4. unresolved external symbol _rint ...
自己编写该函数
int rint(int x)
{
return (int)(x + (x < 0 ? -0.5 : 0.5));
};
5. unresolved external symbol _av_log_level
注释掉源代码 av_log_level =99;
6. 注释掉show_help函数内容。
看看其它问题,一一解决,我不罗列了。然后设置vc环境 command arguments,运行播放。
7.error LNK2001: unresolved external symbol _main解决办法(zz) 参见以下地址的文章
http://www.cnitblog.com/ictfly/archive/2007/01/17/21976.aspx
ffmpeg.c到VC的移植
光潜水,不发言有些不太好,最近要做.net的视频编辑网站,折腾出一个通用的ffmpeg.c移植实现方法,分享。 ffmpeg整个工程不断更新,实际上还是用cygwin或者mingw正常编译就好了。 考虑到有些配置问题导致avformat和avcodec lib中全局变量调用问题,需要添加几个方法。 列表如下, libavcodec/utils.c 添加方法 AVCodec *get_first_avcodec(){ return first_avcodec; } avcodec.h 添加声明 AVCodec *get_first_avcodec(); libavformat/avio.c 添加方法 URLProtocol *get_first_protocol(){ return first_protocol; } avio.h 添加声明 URLProtocol *get_first_protocol(); utils.c 添加方法 AVInputFormat *get_first_iformat(){ return first_iformat; } AVOutputFormat *get_first_oformat(){ return first_oformat; } ffm.c 添加方法 void set_ffm_nopts(int n){ ffm_nopts = n; } avformat.h 添加声明 AVInputFormat *get_first_iformat(); AVOutputFormat *get_first_oformat(); void set_ffm_nopts(int n); libavutil/log.c 添加方法 int get_av_log_level(){ return av_log_level; } void set_av_log_level(int lev){ av_log_level = lev; } log.h 添加声明 int get_av_log_level(); void set_av_log_level(int lev); common.h 添加定义 #if defined(WIN32) && !defined(__cplusplus) #define inline __inline #endif 加两个文件 inttypes1.h #ifndef _INTTYPES1_H #define _INTTYPES1_H #if defined(WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__) # define CONFIG_WIN32 #endif #if defined(WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(EMULATE_INTTYPES) # define EMULATE_INTTYPES #endif #ifndef EMULATE_INTTYPES # include <inttypes.h> #else typedef signed char int8_t; typedef signed short int16_t; typedef signed int int32_t; typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned int uint32_t; # ifdef CONFIG_WIN32 typedef signed __int64 int64_t; typedef unsigned __int64 uint64_t; # else /* other OS */ typedef signed long long int64_t; typedef unsigned long long uint64_t; # endif /* other OS */ #endif /* EMULATE_INTTYPES */ #endif stdint1.h #ifndef _STDINT1_H #define _STDINT1_H #if defined(WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__) # define CONFIG_WIN32 #endif #if defined(WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(EMULATE_STDINT) # define EMULATE_STDINT #endif #ifndef EMULATE_STDINT # include <stdint.h> #else #include "inttypes1.h" typedef int8_t int_least8_t; typedef int16_t int_least16_t; typedef int32_t int_least32_t; typedef uint8_t uint_least8_t; typedef uint16_t uint_least16_t; typedef uint32_t uint_least32_t; #ifndef __STRICT_ANSI__ typedef int64_t int_least64_t; typedef uint64_t uint_least64_t; #endif typedef signed char int_fast8_t; typedef signed long int int_fast16_t; typedef signed long int int_fast32_t; typedef signed long long int int_fast64_t; typedef unsigned char uint_fast8_t; typedef unsigned long int uint_fast16_t; typedef unsigned long int uint_fast32_t; typedef unsigned long long int uint_fast64_t; # define INT64_C(x) x##L #define INT64_MIN (-0x7fffffffffffffffLL-1) #endif /* EMULATE_STDINT */ #endif 可以把工程中所有 include <stdint.h> 替换成 include "stdint1.h" include <inttypes.h> 替换成 include "inttypes1.h" (也可以在make install后,在vc项目中把include/ffmpeg/下所有头文件都改掉) make install 新建vc工程,主要问题是一些宏定义,头文件,c语法的差异。 把ffmpeg.c config.h version.h cmdutils.c cmdutils.h 那些个东东扔进工程,引用lib,include/ffmpeg目录添加到include。 cmdutils.c 把strtoll(arg, (char **)NULL, 10); 改成atol(arg); ffmpeg.c 添加 #ifdef _WIN32 #define snprintf _snprintf #endif #define lrintf(f) ((int32_t)(f)) #define isnan(d) (d!=d) 编译,对于出现的问题见招拆招,大致问题有那么几个。 1、把结构转义给去掉。 例: static AVRational frame_rate = (AVRational){25,1}; => static AVRational frame_rate = {25,1}; 或者直接 xxx.num = aaa; xxx.den = bbb; 2、把AV_TIME_BASE_Q之类的宏调用直接换成声明后调用。 例: AVRational avr = {1, AV_TIME_BASE}/*AV_TIME_BASE_Q*/; pkt.dts += av_rescale_q(input_files_ts_offset[ist->file_index], avr/*AV_TIME_BASE_Q*/, ist->st->time_base); 3、printf format识别 例: fprintf(stderr, "timestamp discontinuity %"PRId64", new offset= %"PRId64"/n", delta, input_files_ts_offset[ist->file_index]); => fprintf(stderr, "timestamp discontinuity %l, new offset= %l/n", delta, input_files_ts_offset[ist->file_index]); compile基本就能过了,在link的时候有些全局变量会找不到。 就使用前面添加到方法, first_avcodec => get_first_avcodec() first_protocol => get_first_protocol() first_iformat => get_first_iformat() first_oformat => get_first_oformat() ffm_nopts => set_ffm_nopts(x) av_log_level => set_av_log_level(x) 然后就可以成功编译,测试运行了。 至于做成动态链接库再用c# marshal,比较简单,就不赘述了。 这玩意搞了我两三个小时,仓促而成,没有深究。可能有问题的,仅作参考吧。 |
AVOutputFormat *get_first_oformat(){ return first_oformat; } 确实我在MCVC7.1 连接 编译好的ffmpeg时,出现 unresolved external symbol _first_iformat |
使用vs2003编译ffplay遇到的问题
我已经加载了sdl库,但是现在出现这个问题: f:/ffmpeg/ffmpeg_src_20060614/libavutil/common.h(304): error C2010: “)” : 宏形参表中的意外 我查了一下,此处的代码是: # ifdef DEBUG # define printf(fmt,...) av_log(NULL, AV_LOG_DEBUG, fmt, __VA_ARGS__) //这一行出错 # else # define dprintf(fmt,...) # endif 是不是我的vs2003的设置有问题,请高手指教。谢谢了。 |
但屏掉以后,还会出现更多其他的问题
比如
f:/ffmpeg/ffmpeg_src_20060614/libavutil/bswap.h(20): error C2054: 在“inline”之后应输入“(”
这行代码是:static always_inline uint16_t bswap_16(uint16_t x)
(always_inline 已经定义成inline)
这种用法看来没什么问题啊。但是报错。郁闷
难道2003不能编译?