b2c信息网

您现在的位置是:首页 > 昨日新闻 > 正文

昨日新闻

ffmpeg编译源码(FFmpeg基础库编程开发)

hacker2022-09-01 00:55:15昨日新闻83
本文目录一览:1、如何用AndroidNDK编译FFmpeg2、

本文目录一览:

如何用Android NDK编译FFmpeg

一、安装cygwin、配置ndk和下载ffmpeg源码

这步就不说了,网上很多教程,再次声明本教程只针对ndk R4这个版本。需要说明的是,本人在cygwin安装路径下的.bash_profile文件中指定的NDK路径如下所示。因为本人装了好几个NDK,因此后面的R4只是个标示。

NDK_R4=/cygdrive/d/android-ndk-r4

export NDK_R4

二、编译前准备和编译

1、因为R4这个NDK比较旧,交叉编译的时候需要在一个Android环境中,那简单,创建一个Android空项目,把整个项目拷出来,在项目下建立一个文件夹jni,把ffmpeg0.6.6的源码拷进去。左图,HelloJni就是我新建的一个项目,Android.mk这时候你还没有,先不用管。右图ffmpeg-0.6.6文件夹的内容要跟我一样,直接就是代码。我这里的ffmpeg_cywin这个文件夹是随便建的,放哪里无所谓的。

2、在ffmpeg-0.6.6下建立一个文件config.sh,内容如下所示。需要注意的是,unix下的换行符和windows下是不一样,如果直接拷贝到windows下的记事本,后面执行这个config.sh的时候会出问题,这里我用的是notepad++编辑的,在编辑-档案格式转换-转换为UNIX格式。(注意,后面的所有的Android.mk的编辑都有此要求)。

简单说一下这个config.sh,PREBUILT和PLATFORM根据你安装ndk的位置而不同,config.sh其实是一个脚本,执行这个脚本的时候又调用了另外一个脚本configure,configure主要是根据编译选项(下面enable disable那些),生成相应的编译配置,就是说你想要编译ffmpeg什么模块就自己定制编译选项的内容。基本上这个文件只要修改一下PREBUILT和PLATFORM就行,其他都不用改。

#!/bin/bash

export PREBUILT=D://android-ndk-r4/build/prebuilt/windows/arm-eabi-4.4.0

export PLATFORM=D://android-ndk-r4/build/platforms/android-8/arch-arm

./configure --target-os=linux \

--arch=arm \

--enable-version3 \

--enable-gpl \

--enable-nonfree \

--disable-stripping \

--disable-ffmpeg \

--disable-ffplay \

--disable-ffserver \

--disable-ffprobe \

--disable-encoders \

--disable-muxers \

--disable-devices \

--disable-protocols \

--enable-protocol=file \

--enable-avfilter \

--disable-network \

--disable-mpegaudio-hp \

--disable-avdevice \

--enable-cross-compile \

--cc=$PREBUILT/bin/arm-eabi-gcc \

--cross-prefix=$PREBUILT/bin/arm-eabi- \

--nm=$PREBUILT/bin/arm-eabi-nm \

--extra-cflags="-fPIC -DANDROID" \

--disable-asm \

--enable-neon \

--enable-armv5te \

--extra-ldflags="-Wl,-T,$PREBUILT/arm-eabi/lib/ldscripts/armelf.x -Wl,-rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib -nostdlib $PREBUILT/lib/gcc/arm-eabi/4.4.0/crtbegin.o $PREBUILT/lib/gcc/arm-eabi/4.4.0/crtend.o -lc -lm -ldl"

3、修改configure文件,找到下图的内容,修改成我这样,这个是用来存放执行脚本过程的临时文件的,我这里用的是D://NDK,你可以设置其他地方,但是要先创建好这个文件夹,放哪里无所谓的。

4、然后在cywin中进入ffmpeg0.6.6文件夹,执行chmod -x config.sh,然后执行./config,此过程需要一定的时间。如果这一步出现问题,很有可能是你config.sh中的PREBUILT和PLATFORM的路径设置不对,或者是你拷贝内容到config.sh的时候没有在UNIX格式下。执行完如下图所示。

5、在ffmpeg-0.6.6下会生成一个config.h文件,编辑它,找到#define restrict restrict这一行,把它改成#define restrict

6、在libavutil/libm.h下,把所有static的方法注释掉或者直接删掉。

7、修改libavcodec,libavfilter,libavformat,libavutil,libpostproc和libswscale目录的MakeFile文件,每个文件中,删除语句

include $( SUBDIR ) ../config.mak 和 include $ (SUBDIR) .. / subdir.mak。

libavcodec下的makefile中搜索inverse.o,把它所在的那一行删掉,要不编译的时候会冲突。

8、在ffmpeg-0.6.6文件夹下,创建av.mk文件(UNIX格式),内容如下:

#LOCAL_PATH is one of libavutil, libavcodec, libavformat, or libswscale

#include $(LOCAL_PATH)/../config-$(TARGET_ARCH).mak

include $(LOCAL_PATH)/../config.mak

OBJS :=

OBJS-yes :=

MMX-OBJS-yes :=

include $(LOCAL_PATH)/Makefile

# collect objects

OBJS-$(HAVE_MMX) += $(MMX-OBJS-yes)

OBJS += $(OBJS-yes)

FFNAME := lib$(NAME)

FFLIBS := $(foreach,NAME,$(FFLIBS),lib$(NAME))

FFCFLAGS = -DHAVE_AV_CONFIG_H -Wno-sign-compare -Wno-switch -Wno-pointer-sign

FFCFLAGS += -DTARGET_CONFIG=\"config-$(TARGET_ARCH).h\"

ALL_S_FILES := $(wildcard $(LOCAL_PATH)/$(TARGET_ARCH)/*.S)

ALL_S_FILES := $(addprefix $(TARGET_ARCH)/, $(notdir $(ALL_S_FILES)))

ifneq ($(ALL_S_FILES),)

ALL_S_OBJS := $(patsubst %.S,%.o,$(ALL_S_FILES))

C_OBJS := $(filter-out $(ALL_S_OBJS),$(OBJS))

S_OBJS := $(filter $(ALL_S_OBJS),$(OBJS))

else

C_OBJS := $(OBJS)

S_OBJS :=

endif

C_FILES := $(patsubst %.o,%.c,$(C_OBJS))

S_FILES := $(patsubst %.o,%.S,$(S_OBJS))

FFFILES := $(sort $(S_FILES)) $(sort $(C_FILES))

9、在jni文件夹下,创建Android.mk(UNIX格式),内容如下:

include $(all-subdir-makefiles)

10、在ffmpeg-0.6.6文件夹下,创建Android.mk,内容如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_STATIC_LIBRARIES := libavformat libavcodec libavutil libpostproc libswscale

LOCAL_MODULE := ffmpeg

include $(BUILD_SHARED_LIBRARY)

include $(call all-makefiles-under,$(LOCAL_PATH))

11、在ffmpeg-0.6.6\libavformat下,创建Android.mk,内容如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

include $(LOCAL_PATH)/../av.mk

LOCAL_SRC_FILES := $(FFFILES)

LOCAL_C_INCLUDES := \

$(LOCAL_PATH) \

$(LOCAL_PATH)/..

LOCAL_CFLAGS += $(FFCFLAGS)

LOCAL_CFLAGS += -include "string.h" -Dipv6mr_interface=ipv6mr_ifindex

LOCAL_LDLIBS := -lz

LOCAL_STATIC_LIBRARIES := $(FFLIBS)

LOCAL_MODULE := $(FFNAME)

include $(BUILD_STATIC_LIBRARY)

12、在ffmpeg-0.6.6\libavcodec下,创建Android.mk,内容如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

include $(LOCAL_PATH)/../av.mk

LOCAL_SRC_FILES := $(FFFILES)

LOCAL_C_INCLUDES := \

$(LOCAL_PATH) \

$(LOCAL_PATH)/..

LOCAL_CFLAGS += $(FFCFLAGS)

LOCAL_LDLIBS := -lz

LOCAL_STATIC_LIBRARIES := $(FFLIBS)

LOCAL_MODULE := $(FFNAME)

include $(BUILD_STATIC_LIBRARY)

13、在ffmpeg-0.6.6\libavfilter、libavutil、libpostproc和libswscale下,创建Android.mk,内容如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

include $(LOCAL_PATH)/../av.mk

LOCAL_SRC_FILES := $(FFFILES)

LOCAL_C_INCLUDES := \

$(LOCAL_PATH) \

$(LOCAL_PATH)/..

LOCAL_CFLAGS += $(FFCFLAGS)

LOCAL_STATIC_LIBRARIES := $(FFLIBS)

LOCAL_MODULE := $(FFNAME)

include $(BUILD_STATIC_LIBRARY)

14、然后在jni目录下,运行$NDK_R4/ndk-build -B,这里的命令需要根据你自己的情况修改,然后就开始编译了。过程需要10来分钟,成功之后,会在libs下生产libffmpeg.so。如果编译出来的libffmpeg.so只有1.5k,得如下修改一下NDK,再重新编译。

把下面红色部分加到NDK的build/core/build-binary.mk里:

LOCAL_STATIC_LIBRARIES := $(call strip-lib-prefix,$(LOCAL_STATIC_LIBRARIES))

LOCAL_STATIC_WHOLE_LIBRARIES := $(call strip-lib-prefix,$(LOCAL_STATIC_WHOLE_LIBRARIES))

...

static_libraries := $(call map,static-library-path,$(LOCAL_STATIC_LIBRARIES))

static_whole_libraries := $(call map,static-library-path,$(LOCAL_STATIC_WHOLE_LIBRARIES))

...

$(call module-add-static-depends,$(LOCAL_MODULE),$(LOCAL_STATIC_LIBRARIES))

$(call module-add-static-depends,$(LOCAL_MODULE),$(LOCAL_STATIC_WHOLE_LIBRARIES))

...

$(LOCAL_BUILT_MODULE): $(static_libraries) $(static_whole_libraries) $(shared_libraries)

...

$(LOCAL_BUILT_MODULE): PRIVATE_STATIC_LIBRARIES := $(static_libraries)

$(LOCAL_BUILT_MODULE): PRIVATE_WHOLE_STATIC_LIBRARIES := $(static_whole_libraries)

接着再将最外层ffmpeg/Android.mk里面的LOCAL_STATIC_LIBRARIES改成LOCAL_STATIC_WHOLE_LIBRARIES

如何用vc6编译ffmpeg,并单步调试

目前官方ffmpeg的最新版本为0.9, 我们就以此为例:

1. 下载最新git版本的源代码(, 本例下载的是2011-12-12版本)

2. 放到MSYS环境里配置,生成config.h文件。mingw gcc是能顺利编译通过整个项目的,并生成最新版的ffmpeg。

3. 建立vc6工程,把相关代码都加入到工程中。由于在vc生成的obj都在一个目录下,所以需要修改文件名,让其不重名。

4. 安装intel compiler 11编译器,单独提取其icl.exe及相关include目录,替换掉vc6自带的cl.exe, 在工程设置里加上/Qstd=c99,用于支持C99语法。

5. 安装intel compiler 10编译器,单独提取lib目录,因为此版本调试库的结构能完美支持vc6的调试信息。

6. 在vc6的options里设置include/exe/lib查找目录,指向intel编译器。

7. 开始修改代码,添加C99的相关linux头文件, 用于支持vc6, (unistd.h, stdint.h, inttypes.h, getopt.h)

8. 添加C99和linux的相关实现代码,ffmpeg需要用到: getopt_long, strtoll, gettimeofday, atoll, usleep等

9. 修改windows的相关兼容代码,GetWindowLongPtr - GetWindowLong, GWLP_USERDATA

10. 去除硬件加速libavcodec代码,和依赖库代码。选择所需要的模块,修改相关的allcodec.c, alldevices.c, allfilters.c, allformats.c

11. 加上链接库,sdl.lib, winmm.lib, dxguid.lib, wsock32.lib

12. 在os_support.c里,把winsock2.h移动到文件最前面。

13. 如果是ffmpeg, 已经能顺利编译了。如果是ffplay,还需要编译静态sdl, 并链接。

14. 等等,音频运行不正确?有雪花声?因为还需要替换所有文件里的math.h为mathimf.h, 默认的rint等数学函数和gcc不兼容。

15. ok, 大功告成,纯C版本完美运行。

16. 由于ffmpeg0.9在c文件里,添加了一些intel compiler不支持的mmx语法,所以编译mmx/sse加速版本时,一小部分.c文件需要依赖mingw gcc编译成.o文件,再通过vc6的lib.exe工具转换成lib,让vc6链接上。当然还要加上yasm编译的很多汇编obj.

如何在windows中编译ffmpeg 2.6.1以及 NVENC硬编码的尝试

4)然后在mingw的控制台中进入ffmpeg源码目录,并执行命令:./configure --enable-memalign-hack 生成编译时所需的Makefile文件。然后执行 make 命令,就可以生成相应的exe文件,如ffmpeg.exe、 ffplay_g.exe、ffmpeg_g.exe 等。

发表评论

评论列表

  • 痴者寻倌(2022-09-01 04:34:02)回复取消回复

    dir)include $(CLEAR_VARS)include $(LOCAL_PATH)/../av.mkLOCAL_SRC_FILES := $(FFFILES)LOCAL_C_INCLUDES := \$(LOCAL_PATH) \$(LOC

  • 北槐织谜(2022-09-01 09:13:34)回复取消回复

    ARS)include $(LOCAL_PATH)/../av.mkLOCAL_SRC_FILES := $(FFFILES)LOCAL_C_INCLUDES := \$(LOCAL_PATH) \$(LOCAL_PATH)/..LOCAL_CFLAG

  • 莣萳卮留(2022-09-01 08:40:21)回复取消回复

    和 include $ (SUBDIR) .. / subdir.mak。libavcodec下的makefile中搜索inverse.o,把它所在的那一行删掉,要