FFmpeg 编译

环境 Linux
NDk版本:13
FFmpeg 版本3.3.3

Linux 环境下配置NDK省略。。。。
FFmpeg 解压省略。。。。。

开始进入正题了 稍等片刻

首先进ffmpeg 下的configure 文件中的:

SLIBNAME_WITH_MAJOR='$(SLIBNAME).$(LIBMAJOR)'

LIB_INSTALL_EXTRA_CMD='$$(RANLIB)"$(LIBDIR)/$(LIBNAME)"'

SLIB_INSTALL_NAME='$(SLIBNAME_WITH_VERSION)'

SLIB_INSTALL_LINKS='$(SLIBNAME_WITH_MAJOR)$(SLIBNAME)'

修改成:

SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)'

LIB_INSTALL_EXTRA_CMD='$$(RANLIB)"$(LIBDIR)/$(LIBNAME)"'

SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'

SLIB_INSTALL_LINKS='$(SLIBNAME)'

继续往下走
配置ffmpeg 编译所需要的sh文件

#!/bin/bash
NDK=/home/qichaungguo/NDK/android-ndk-r13
SYSROOT=$NDK/platforms/android-16/arch-arm/
TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64

CPU=arm
PREFIX=/home/qichaungguo/ff
ADDI_CFLAGS="-marm"

function build_one
{
./configure \
--prefix=$PREFIX \
--enable-shared \
--disable-static \
--disable-doc \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-ffserver \
--disable-doc \
--disable-symver \
--enable-small \
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
--target-os=linux \
--arch=arm \
--enable-cross-compile \
--sysroot=$SYSROOT \
--extra-cflags="-Os -fpic $ADDI_CFLAGS" \
--extra-ldflags="$ADDI_LDFLAGS" \
$ADDITIONAL_CONFIGURE_FLAG
make clean
make
make install
}

build_one

注意替换自己的路径其中PREFIX 是生成的目录。

等待个几分钟吧 一切都好了 就会生成一个include 和lib目录

我们用Android studio 测试一番。

来创建一个项目 ,,,,几分钟过后创建好了。

在main 目录下创建一个jni目录,将编译后的ffmpeg生成的include文件拷贝进去,将lib中的so也拷贝进去。
大概就是这样子:

这里写图片描述

创建一个cpp文件 写一个测试ffmpeg的类子。

开始上源码:

//
// Created by chuangguo.qi on 2017/8/3.
//
extern "C" {
#include <jni.h>
#include <libavformat/avformat.h>"
#define  LOG_TAG    "FFMPEGSample"
#include <android/log.h>
#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
#include "include/libavcodec/avcodec.h"
}

extern "C" {

jint getFFmpegText(JNIEnv *env, jobject obj, jint id) {

    av_register_all();
    AVCodecID avCodecID = AV_CODEC_ID_H264;
    LOGI("%d",avCodecID);
    LOGI("%d",id);
    AVCodec *vCodec = avcodec_find_decoder(avCodecID);
    if (vCodec!=NULL){
        return 0;
    } else{
        return -1;
    }

}

static JNINativeMethod gMethods[]={
        //(I) 参数  I 返回值
        {"getFFmpegText", "(I)I", (void *)getFFmpegText},
};

static const char *ClassName = "com/android/cgcxy/ffmpegdemo/JniUtils";

static int registerNativeMethods(JNIEnv *env) {
    jclass clazz;
    clazz = env->FindClass(ClassName);
    if (clazz == NULL) {
        LOGI("class==null");
        return JNI_FALSE;
    }

    if(env->RegisterNatives(clazz, gMethods, sizeof(gMethods)/sizeof(gMethods[0])) < 0){
        return JNI_FALSE;
    }

    return JNI_TRUE;
}

jint JNI_OnLoad(JavaVM* vm, void* reserved) {
    JNIEnv* env = NULL;
    jint result = -1;
    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK)
    {
         LOGE("ERROR: GetEnv failed\n");
        goto bail;
    }

    if (registerNativeMethods(env) < 0) {
         LOGE("ERROR: jnitest native registration failed\n");
        goto bail;
    }
    result = JNI_VERSION_1_4;

    bail:
    return result;
}

}

一切准备就绪 接下我们就去配置 开始生成so了 哈哈 继续哦,,,

创建mk文件

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := avcodec
LOCAL_SRC_FILES := libavcodec-57.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := avformat
LOCAL_SRC_FILES :=libavformat-57.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := avutil
LOCAL_SRC_FILES := libavutil-55.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := swresample
LOCAL_SRC_FILES := libswresample-2.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := swscale
LOCAL_SRC_FILES := libswscale-4.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_SRC_FILES := ffmeng.cpp
LOCAL_LDLIBS += -llog -lz -landroid
LOCAL_MODULE := VideoPlay
LOCAL_C_INCLUDES += $(LOCAL_PATH)/include

LOCAL_SHARED_LIBRARIES:= avcodec avformat avutil swresample swscale
include $(BUILD_SHARED_LIBRARY)

这就ok了 ,,,来来 再去走最后一步,配置build:

externalNativeBuild {
            ndkBuild  {
                abiFilters 'armeabi'
                cppFlags "-fpermissive", "-fexceptions"
                cFlags "-Wno-error=format-security"
            }
        }

        ndk {
            stl 'gnustl_static'
        }
    }

    sourceSets {
        main {
            jniLibs.srcDir file('jni/')
        }
    }

    externalNativeBuild {
        ndkBuild {
            path 'src\\main\\jni\\Android.mk'


        }
    }

奇迹将要发生了。。。点击 make project ,在ndkbuild 下会生成所以的so 库 完美 哈哈 结束

哈哈 等等 其中还有个坑 给忘了。。。

common.h 文件会报错 解决办法如下:

//最顶端添加
extern "C"
{
#ifdef __cplusplus
#define __STDC_CONSTANT_MACROS
#endif

}
//在
#if defined(__cplusplus) && !defined(__STDC_CONSTANT_MACROS) && !defined(UINT64_C)
#error missing -D__STDC_CONSTANT_MACROS / #define __STDC_CONSTANT_MACROS
#endif

//下面添加如下代码;

/*#ifndef __MICloudPub___H264Decoder__
#define __MICloudPub___H264Decoder__

#ifndef UINT64_C
#define UINT64_C(value) __CONCAT(value, ULL)
#endif*/

#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 */

//解决UINT64_C没定义的问题
#ifndef INT64_C
#define INT64_C(c) (c##LL)
#define UINT64_C(c)  (c##ULL)
#endif

Beautiful

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值