DSP

ffmpeg移植到wince

2019-07-13 20:20发布

 

由于系统Windows XP 和 Windows CE的差异, 导致移植到Windows XP上的ffmpeg动态连接库并不能在WinCE上使用, 所以需重新移植一番. 一、在开始移植前,需要做些准备工作: 1.1  下载 cygwin 工具(Setup.exe), 注意下载 1.7.xx的版本  http://www.cygwin.com/ 1.2  下载 cegcc 交叉编译工具(cegcc_mingw32ce_cygwin1.7_r1375.tar.bz2)  http://sourceforge.net/projects/cegcc/files/?source=navbar  1.3  下载 ffmpeg 源码包,http://www.ffmpeg.org/download.html  我使用的是 FFmpeg 0.10.6 "Freedom" 的版本,版本选择不同,编译的时候会导致一些微小的差异 1.4  参考 http://www.ffmpeg.org/platform.html#Cross-compilation-for-Windows-with-Linux-1  了解相关情况   二、工具的安装 2.1  Cygwin安装     执行setup.exe 确保网络正常连接     在Cygwin Setup - Select Package这步时,需选择这些包:      autobuild, autoconf, automake, binutils, gcc, gcc-core, gcc-g++, gcc-mingw, gcc-mingw-core, gcc-mingw-g++, gcc4, gcc4-core, gcc4-g++, gccmakedep, gdb, git, make, makedepend, mingw-binutils, mingw-gcc, mingw-gcc-core, mingw-gcc-g++, mingw-runtime, mingw-zlib, pkg-config, w32api-runtime, yasm, gettext, texi2html, bc, libogg-devel, libvorbis-devel, vim ffmpeg移植到wince - chfj007 - 重复造轮子  2.2 Cegcc交叉编译器安装  把 cegcc_mingw32ce_cygwin1.7_r1375.tar.bz2  复制到 D:cygwinhome (注意自己的安装路径,默认装的是在C盘)目录下  启动 Cygwin Terminal   cd /home   tar xjvf cegcc_mingw32ce_cygwin1.7_r1375.tar.bz2    (千万要小心,不要把Cygwin安装到 FAT 文件系统的分区上,不然就等着悲吹咯!!!安装Cygwin到FAT32的分区会导致ln硬连接失败, 这样tar解包的时候,会缺少一些arm-mingw32ce-xx文件,想自己用ln命令创建,哈哈,命令执行失败报操作不允许 not permission,TNND,fuck 他大爷的)  修改 D:cygwinetcprofile 文件,在文件末尾增加相应的PATH路径  export PATH="/home/mingw32ce/bin:$PATH"  执行source /etc/profile使设置生效    3.1 ffmpeg的配置 ./configure --enable-memalign-hack
--target-os=mingw32ce
--arch=arm
--cpu=armv4                                                      ---------- 指令集 请根据设备的情况选择(armv4, armv6, armv7...)
--enable-cross-compile
--cross-prefix=arm-mingw32ce-
--enable-shared
--disable-static
--disable-doc
--disable-ffmpeg
--disable-ffplay
--disable-ffprobe
--disable-ffserver
--disable-network
--extra-ldflags=--enable-auto-import
--prefix=/home/wince 把它写到mycecfg.sh中,接着 chmod +x cecfg.sh ,然后执行 ./mycecfg.sh  结果显示: License: LGPL version 2.1 or later
Creating config.mak and config.h... WARNING: arm-mingw32ce-pkg-config not found, library detection may fail.   ------------(注意:有些警告不能忽视,不然你可以试试) 解决办法 cd /home/mingw32ce/bin cp /usr/bin/pkg-config.exe arm-mingw32ce-pkg-config.exe 接着再 make distclean ./mycecfg.sh   3.2 编译 make 3.2.1 /home/mingw32ce/bin/../lib/gcc/arm-mingw32ce/4.4.0/../../../../arm-mingw32ce/include/errno.h:12:25: error: no include path in which to search for errno.h
common.mak:45: recipe for target `libavdevice/alldevices.o' failed
make: *** [libavdevice/alldevices.o] Error 1
规避办法:  修改 /home/mingw32ce/arm-wince-mingw32ce/include/errno.h
 注释 //#ifdef __COREDLL__
         //# include_next
         //#else /* __COREDLL__ */          //#endif /* Not __COREDLL__ */ ============================================================================================================== 3.2.2 libavcodec/arm/dsputil_arm.S: Assembler messages:
libavcodec/arm/dsputil_arm.S:718: Error: selected processor does not support `bx lr'
common.mak:54: recipe for target `libavcodec/arm/dsputil_arm.o' failed
make: *** [libavcodec/arm/dsputil_arm.o] Error 1
规避办法: 修改 libavcodec/arm/dsputil_arm.S  将 bx lr 改为 mov pc, lr libavcodec/arm/flacdsp_arm.S: Assembler messages:
libavcodec/arm/flacdsp_arm.S:55: Error: selected processor does not support `bxle lr'
libavcodec/arm/flacdsp_arm.S:92: Error: selected processor does not support `bxle lr'   修改 libavcodec/arm/flacdsp_arm.S  将 bxle lr 改为 movle pc, lr   另外的办法是:改变arm指令版本 --arch=arm --cpu=arm9tdmi 原因是:armv4不支持bx =============================================================================================================== 3.2.3  libavutil/log.c: In function 'colored_fputs':
libavutil/log.c:68: error: implicit declaration of function 'getenv'
common.mak:45: recipe for target `libavutil/log.o' failed
make: *** [libavutil/log.o] Error 1 根本解决办法:有兴趣的,可以参看大牛们的 http://ffmpeg.org/pipermail/ffmpeg-devel/2009-August/060679.html 的相关主题讨论 无奈的规避办法: 修改libavutil/log.c文件的代码    //use_color = getenv("AV_LOG_FORCE_COLOR") && !getenv("NO_COLOR") &&
   //           !getenv("AV_LOG_FORCE_NOCOLOR");
   use_color = 256;   =============================================================================================================== 3.2.4 libavutil/random_seed.c: In function 'get_generic_seed':
libavutil/random_seed.c:50: error: implicit declaration of function 'clock'
common.mak:45: recipe for target `libavutil/random_seed.o' failed
make: *** [libavutil/random_seed.o] Error 1
规避办法: 修改 libavutil/random_seed.c 文件 static uint32_t get_generic_seed(void)
{
    //clock_t last_t  = 0;
    time_t last_t  = 0;
    int bits        = 0;
    uint64_t random = 0;
    unsigned i;
    float s = 0.000000000001;     for (i = 0; bits < 64; i++) {
        time_t t = time((time_t*)NULL);
        //clock_t t = clock();
    if (last_t && fabs(t - last_t) > s || t == (clock_t) -1) {
            if (i < 10000 && s < (1 << 24)) {
                s += s;
                i = t = 0;
            } else {
                random = 2 * random + (i & 1);
                bits++;
            }
        }
        last_t = t;
    }
#ifdef AV_READ_TIME
    random ^= AV_READ_TIME();
#else
    random ^= time((time_t*)NULL);
    //random ^= clock();
=============================================================================================================== 3.2.5 /home/ffmpeg-0.10.6/libavutil/file.c:172: relocation truncated to fit  : ARM_26 against undefined symbol `_errno'
libavutil/file.o: In function `av_file_map':
/home/ffmpeg-0.10.6/libavutil/file.c:89: undefined reference to `_get_osfhandle'
/home/ffmpeg-0.10.6/libavutil/file.c:89: relocation truncated to fit:  ARM_26 against undefined symbol `_get_osfhandle'
/home/ffmpeg-0.10.6/libavutil/file.c:91: undefined reference to `Crea teFileMappingA'
/home/ffmpeg-0.10.6/libavutil/file.c:91: relocation truncated to fit:  ARM_26 against undefined symbol `CreateFileMappingA'
/home/ffmpeg-0.10.6/libavutil/file.c:54: undefined reference to `_errno'
/home/ffmpeg-0.10.6/libavutil/file.c:54: relocation truncated to fit:  ARM_26 against undefined symbol `_errno'
/home/ffmpeg-0.10.6/libavutil/file.c:61: undefined reference to `_errno'
/home/ffmpeg-0.10.6/libavutil/file.c:61: relocation truncated to fit: ARM_26 against undefined symbol `_errno'
collect2: ld returned 1 exit status
library.mak:97: recipe for target `libavutil/avutil-51.dll' failed
make: *** [libavutil/avutil-51.dll] Error 1
规避办法: 凡涉及 errno 的变量注释掉,比如  err = AVERROR(errno);  修改为 err = -1;        /*HANDLE mh, fh = (HANDLE)_get_osfhandle(fd);         mh = CreateFileMapping(fh, NULL, PAGE_READONLY, 0, 0, NULL);
        if (!mh) {
            av_log(&file_log_ctx, AV_LOG_ERROR, "Error occurred in CreateFileMapping() ");
            close(fd);
            return -1;
        }         ptr = MapViewOfFile(mh, FILE_MAP_READ, 0, 0, *size);
        CloseHandle(mh);
        if (!ptr) {
            av_log(&file_log_ctx, AV_LOG_ERROR, "Error occurred in MapViewOfFile() ");
            close(fd);
            return -1;
        }*/
         close(fd);
        return -1; =============================================================================================================== 3.2.6 LINK : warning LNK4012: ???arm-wince????Ч?????????ARM, EBC, IA64, MIPS, MIPS16, MIPSFPU, MIPSFPU16, SH4, THUMB, X64, or X86????????????
LINK : warning LNK4068: δ??? /MACHINE?????????? X86
   ????????? libavutil/avutil.lib ????? libavutil/avutil.exp
LD      libavcodec/avcodec-53.dll
Info: resolving ff_log2_tab by linking to __imp_ff_log2_tab (auto-import)
Info: resolving ff_sqrt_tab by linking to __imp_ff_sqrt_tab (auto-import)
Info: resolving av_reverse by linking to __imp_av_reverse (auto-import)
Info: resolving av_md5_size by linking to __imp_av_md5_size (auto-import)
Info: resolving av_pix_fmt_descriptors by linking to __imp_av_pix_fmt_descriptors (auto-import)
Creating library file: libavcodec/libavcodec.dll.a
/home/mingw32ce/bin/../lib/gcc/arm-mingw32ce/4.4.0/../../../../arm-mingw32ce/bin/ld: warning: auto-importing has been activated without --enable-auto-import specified on the command line.
This should work unless it involves constant data structures referencing symbols from auto-imported DLLs.
lib.exe /machine:arm-wince /def:libavcodec/avcodec-53.def /out:libavcodec/avcodec.lib
解决办法: 修改 config.mak 文件 将   LDFLAGS= --enable-auto-import -Wl,--as-needed -Wl,--warn-common -Wl,-rpath-link=libpostproc:libswresample:libswscale:libavfilter:libavdevice:libavformat:libavcodec:libavutil 修改为 LDFLAGS= -Wl,--enable-auto-import -Wl,--as-needed -Wl,--warn-common -Wl,-rpath-link=libpostproc:libswresample:libswscale:libavfilter:libavdevice:libavformat:libavcodec:libavutil 或者 --extra-ldflags=--enable-auto-import 修改为 --extra-ldflags=“-Wl,--enable-auto-import"   将 LIBTARGET=arm-wince   修改为  LIBTARGET=arm   如果不想修改也没关系,只是编译出来的ffmpeg动态库DLL,  在VC项目中使用时,会报链接的错误,找不到相关函数例如 avformat_open_input的实现。 在cmd中, 用 dumpbin /exports  xx.dll >> 1.txt , 在1.txt中查找到是 _avformat_open_input  , 多了一个下划线 。  这个时候需要对xx.dll 重新执行 lib /machine:arm /def:xx.def /out:xx.lib 。 注意:若cmd 提示无命令,请先设置vs的相关环境变量。 ==============================================================================================================
编译成功 Creating library file: libswscale/libswscale.dll.a
lib.exe /machine:arm /def:libswscale/swscale-2.def /out:libswscale/swscale.lib
Microsoft (R) Library Manager Version 9.00.21022.08
Copyright (C) Microsoft Corporation.  All rights reserved.    ????????? libswscale/swscale.lib ????? libswscale/swscale.exp
LD      libavfilter/avfilter-2.dll
Creating library file: libavfilter/libavfilter.dll.a
lib.exe /machine:arm /def:libavfilter/avfilter-2.def /out:libavfilter/avfilter.lib
Microsoft (R) Library Manager Version 9.00.21022.08
Copyright (C) Microsoft Corporation.  All rights reserved.    ????????? libavfilter/avfilter.lib ????? libavfilter/avfilter.exp
LD      libavdevice/avdevice-53.dll
Creating library file: libavdevice/libavdevice.dll.a
lib.exe /machine:arm /def:libavdevice/avdevice-53.def /out:libavdevice/avdevice.lib
Microsoft (R) Library Manager Version 9.00.21022.08
Copyright (C) Microsoft Corporation.  All rights reserved.    ????????? libavdevice/avdevice.lib ????? libavdevice/avdevice.exp --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 然后 make install $ ls -l
总用量 11152
-rw-r--r-- 1 chfj None  364764 三月 17 18:15 avcodec.lib
-rwxr-xr-x 1 chfj None 9029651 三月 17 18:15 avcodec-53.dll
-rw-r--r-- 1 chfj None    2638 三月 17 18:15 avdevice.lib
-rwxr-xr-x 1 chfj None   11283 三月 17 18:15 avdevice-53.dll
-rw-r--r-- 1 chfj None   39214 三月 17 18:15 avfilter.lib
-rwxr-xr-x 1 chfj None  231443 三月 17 18:15 avfilter-2.dll
-rw-r--r-- 1 chfj None  141968 三月 17 18:15 avformat.lib
-rwxr-xr-x 1 chfj None  955923 三月 17 18:15 avformat-53.dll
-rw-r--r-- 1 chfj None   40876 三月 17 18:15 avutil.lib
-rwxr-xr-x 1 chfj None  153107 三月 17 18:15 avutil-51.dll
-rw-r--r-- 1 chfj None    5758 三月 17 18:15 swresample.lib
-rwxr-xr-x 1 chfj None   31232 三月 17 18:15 swresample-0.dll
-rw-r--r-- 1 chfj None   19326 三月 17 18:15 swscale.lib
-rwxr-xr-x 1 chfj None  198675 三月 17 18:15 swscale-2.dll chfj@chen-feiyang /home/wince/bin
$ file avcodec-53.dll
avcodec-53.dll: PE32 executable (DLL) (Windows CE) ARM (stripped to external PDB), for MS Windows


四、测试 把 avcodec-53.dll、avfilter-2.dll、avformat-53.dll、avutil-51.dll、swresample-0.dll、swscale-2.dll、avdevice-53.dll 和测试的xx.exe 传到自己的WINCE设备上,执行xx.exe xx.exe无任何反应,这时还需有相应的 mfc80u.dll, mfcm80u.dll, atl80.dll 等,外加 libgcc_s_sjlj-1.dll(位于D:cygwinhomemingw32cein) 。   后记 当上面都进行得很high的,运行调用ffmpeg函数的测试demo,demo铛弹出一出错信息框,大意是程序发生了一系列错误,需要关闭!接着通过串口打印的调试信息弹出一些关于"Data Abort"的信息。我靠,马乐个比,老天你这是在玩我吗??? 心情无比郁闷,没招了,头好大!这下如何事好,交不了差鸟。 郁闷了一两天,忽然想起还有MingGW这个工具,死马当活马医。在MingGW上重来一回(只需装cegcc交叉编译器,再把cygwin1.dll、cygz.dll等几个拷贝到MingGW上即可,按出错的提示拷相关的dll)。怀着忐忑 的心情,把编好的dll 在设备上跑,阿哈,这回运行正常,哈哈,交差。 令我疑惑的事,操作步骤是一样的,一定是在MingGW我修改了什么地方和在Cygwin上的不同,但又想不起来了。