vc 编译ffplay

本文记录了在VC环境下编译FFmpeg的ffplay的过程,包括移植ffmpeg.c和相关头文件到VC工程,解决#include 'version.h'找不到、_main重复定义、未解析的外部符号等问题,并提供了错误解决方法和链接。
摘要由CSDN通过智能技术生成

编解码工具 2009-03-22 11:28:11 阅读918 评论0   字号: 订阅

. 下载配置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正常编译就好了。
考虑到有些配置问题导致avformatavcodec 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的设置有问题,请高手指教。谢谢了。
最简单的办法,注释掉://define printf(fmt,...) av_log(NULL, AV_LOG_DEBUG, fmt, __VA_ARGS__)
是,我一开始也是这么搞的
但屏掉以后,还会出现更多其他的问题
比如
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不能编译?
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
本系列 FFMPEG 编译文档只针对 FFMPEG 2 1 1 版本 不同版本参考本文档不一定能编 译成功 在 windows 下单纯就学习 FFMPEG 而言 可以不用编译它 因为官方提供有编译好 的库 开发者可以直接用提供的库进行学习 但官方提供的只有动态链接库 想用静态库还 是要自己编译 我用 FFMPEG 主要是在 windows 平台开发视频监控客户端和网页播放插件 以及后期手机上的播放器 我的这些 肯定要为自己的系统需求专门精简 所以也要自己编 译 先拿 windows 开刀 在这上练练手 当时哪止手 腿都练折了 也熟悉熟悉编译过程 考虑到在 windows 下基于 MinGW 编译 FFMPEG 是一个复杂 庞大的工程 为了提高初学者 的信心 我将整个编译过程作了一个分割调整 分成初级篇 中级篇和高级篇 在初级篇中 只简单的编译 FFMPEG 和它的例子程序 ffmpeg exe ffplay exe;中级篇加上常见的一些第三 方库支持 比如 H264 编码的 x264 库 AVS 编码的 xavs 库 MP3 编码的 mp3lame 库 还有 一些 AAC 编解码库等;高级篇对 FFMPEG 2 1 1 版本支持的所有第三方库 尽量全编译进去 做一个全面的支持的 FFMPEG 编译 ">本系列 FFMPEG 编译文档只针对 FFMPEG 2 1 1 版本 不同版本参考本文档不一定能编 译成功 在 windows 下单纯就学习 FFMPEG 而言 可以不用编译它 因为官方提供有编译好 的库 开发者可以直接用提供的库进行学习 但官方提供的只有动态 [更多]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值