Chinaunix首页 | 论坛 | 博客
  • 博客访问: 83798
  • 博文数量: 14
  • 博客积分: 117
  • 博客等级: 民兵
  • 技术积分: 150
  • 用 户 组: 普通用户
  • 注册时间: 2012-04-08 12:40
文章分类

全部博文(14)

文章存档

2013年(2)

2012年(12)

我的朋友

分类: Android平台

2013-03-20 11:27:45

 本文介绍从开始下载直到使用ffmpeg来进行ndk简单应用的详细过程。

 环境是ubuntu 10.04LTS 虚拟机是vmware

一、            ffmpeg的安装

1、  下载

a.       安装git。在终端下执行apt-get install git-core,注意是在root 权限下执行。

b.       下载最新版本的ffmpeg。在终端输入git clone git://source.ffmpeg.org/ffmpeg.git ffmpeg

2、  编译

a.       进入前面下载的ffmpeg目录下,创建一个config.sh文件,里面内容如下:

export PREBUILT=/home/android/android-ndk-r8b/toolchains/arm-linux-androideabi-4.6

export PLATFORM=/home/android/android-ndk-r8b/platforms/android-14/arch-arm

export TMPDIR=/home/work/tmp

./configure \

--target-os=linux \

--arch=arm \

--disable-ffmpeg \

--disable-ffplay \

--disable-ffprobe \

--disable-ffserver \

--disable-avdevice \

--disable-avfilter \

--disable-postproc \

--disable-swresample \

--disable-avresample \

--disable-symver \

--disable-debug \

--disable-stripping \

--disable-yasm \

--disable-asm \

--enable-gpl \

--enable-version3 \

--enable-nonfree \

--disable-doc \

--enable-static \

--disable-shared \

--enable-cross-compile \

--prefix=/home/android/ffmpeg \

--cc=$PREBUILT/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc \

--cross-prefix=$PREBUILT/prebuilt/linux-x86/bin/arm-linux-androideabi- \

--nm=$PREBUILT/prebuilt/linux-x86/bin/arm-linux-androideabi-nm \

--extra-cflags="-fPIC -DANDROID -I$PLATFORM/usr/include" \

--extra-ldflags="-L$PLATFORM/usr/lib -nostdlib"

c.       改变权限  chmod +x config.sh

d.       执行  ./config.sh  此时会提示有关一些静态变量相关的错误,需要对libavutil/libm.h 进行一些修改:ctrl+f 查找到static ,把带有这个关键字的方法注释掉,再重新./config.sh

e.       make    

f.       make install

以上几步就可以编译出静态库文件libavcodec libavformat libavutil libswscale及其头文件

库和头文件都是在libavcodec libavformat libavutil libswscale 这几个目录下。

二、            ffmpegandroid的使用(编程)

1建立一个Android应用工程,创建文件TestNDK.java

package com.myprj.testndk;

import android.app.Activity;

import android.os.Bundle;

import android.widget.TextView;

public class TestNDK extends Activity {

         @Override

         protected void onCreate(Bundle savedInstanceState) {

                   super.onCreate(savedInstanceState);

                   setContentView(R.layout.activity_test_ndk);

                   TextView tv=new TextView(this);

        tv.setText(stringFromJNI());

        setContentView(tv);

    }

   

    public native String stringFromJNI();

    public native String unimplementedStringFromJNI();

   

    static{

     System.loadLibrary("TestNDK");  //注意名称要跟下面生成的模块名称保持一致

    }

}

eclipse编译该工程,生成相应的.class文件,这步必须在下一步之前完成,因为生成.h文件需要用到相应的.class文件。

 

2. 编写相应的C/C++代码

a. 生成相应.h文件:

首先在终端下进入刚刚建立的tetsandroid工程的目录,然后cd到工程目录文件夹下,

输入javah -classpath bin/classes/ -jni com.myprj.testndk.TestNDK

这一步特别需要注意类的路径,否者很有可能无法生成头文件

成功后生成一个com_myprj_testndk_TestNDK.h文件

我原本是想将该.h文件放在jni目录下的,无耐,不能在jni文件夹下生成,在工程文件下生成,只能将.h文件拷贝到jni目录下。若哪位清楚原因麻烦告知下,谢谢。

/* DO NOT EDIT THIS FILE - it is machine generated */

#include

/* Header for class com_myprj_testndk_TestNDK */

#ifndef _Included_com_myprj_testndk_TestNDK

#define _Included_com_myprj_testndk_TestNDK

#ifdef __cplusplus

extern "C" {

#endif

/*

 * Class:     com_myprj_testndk_TestNDK

 * Method:    stringFromJNI

 * Signature: ()Ljava/lang/String;

 */

JNIEXPORT jstring JNICALL Java_com_myprj_testndk_TestNDK_stringFromJNI

  (JNIEnv *, jobject);

/*

 * Class:     com_myprj_testndk_TestNDK

 * Method:    unimplementedStringFromJNI

 * Signature: ()Ljava/lang/String;

 */

JNIEXPORT jstring JNICALL Java_com_myprj_testndk_TestNDK_unimplementedStringFromJNI

  (JNIEnv *, jobject);

#ifdef __cplusplus

}

#endif

#endif
上面代码中的JNIEXPORT JNICALL jni的宏。这个函数名比较长,不过很有规律的, 完全按照:java_pacakege_class_mathod 形式来命名。

 

b. 编写相应的.c文件:jni/TestNDK.c

#include

#include

#include "avcodec.h"

#include "avformat.h"

#include "avutil.h"

#include "swscale.h"

JNIEXPORT jstring JNICALL Java_com_myprj_testndk_TestNDK_stringFromJNI

  (JNIEnv* env, jobject thiz)

{

      char str[25];

      sprintf(str, "%d", avcodec_version());

      return (*env)->NewStringUTF(env,str);

}

3. 编译TestNDK.c 生成相应的库

a. 编写jni/Android.mk文件

Android.mk 文件是Android makefile文件,内容如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := avformat

LOCAL_SRC_FILES := libavformat.a

LOCAL_CFLAGS :=-Ilibavformat

LOCAL_EXPORT_C_INCLUDES := libavformat

LOCAL_EXPORT_CFLAGS := -Ilibavformat

LOCAL_EXPORT_LDLIBS := -llog

include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)

LOCAL_MODULE := avcodec

LOCAL_SRC_FILES := libavcodec.a

LOCAL_CFLAGS :=-Ilibavcodec

LOCAL_EXPORT_C_INCLUDES := libavcodec

LOCAL_EXPORT_CFLAGS := -Ilibavcodec

LOCAL_EXPORT_LDLIBS := -llog

include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)

LOCAL_MODULE := avutil

LOCAL_SRC_FILES := libavutil.a

LOCAL_CFLAGS :=-Ilibavutil

LOCAL_EXPORT_C_INCLUDES := libavutil

LOCAL_EXPORT_CFLAGS := -Ilibavutil

LOCAL_EXPORT_LDLIBS := -llog

include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)

LOCAL_MODULE := swscale

LOCAL_SRC_FILES :=libswscale.a

LOCAL_CFLAGS :=-Ilibavutil -Ilibswscale

LOCAL_EXPORT_C_INCLUDES := libswscale

LOCAL_EXPORT_CFLAGS := -Ilibswscale

LOCAL_EXPORT_LDLIBS := -llog -lavutil

include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)

LOCAL_MODULE    := TestNDK          #注意该名称跟上面的一致

LOCAL_C_INCLUDES += $(LOCAL_PATH) \

    $(LOCAL_PATH)/include

LOCAL_SRC_FILES := TestNDK.c

LOCAL_LDLIBS    := -L$(LOCAL_PATH) -lm -lz

LOCAL_STATIC_LIBRARIES := avformat avcodec avutil swscale

include $(BUILD_SHARED_LIBRARY)

c. 将已编译好的ffmpeg相关的静态库和头文件拷贝到jni目录下,具体有哪些看截图

 

 d.进入到jni目录下进行编译 输入/home/android/android-ndk-r8b/ndk-build


e.
生成.so后再对java工程进行编译 run as。我的是用真机调试,截图如下:


其中
3604836就是ffmpeg的版本信息。

本例子只是一个简单的测试demo,以后大家要扩展自己的解码器应该查看与ffmpeg相关文档。本人接下来也是继续进行相关开发。

注:本人用此方法并没有像网上说的会出现很多相关问题。

刚开始接触ffmpeg,由于水平有限,若有不当之处望不吝指出。

本文参考的网站有:

http://blog.csdn.net/jacklam200/article/details/8548675

http://my.oschina.net/wangqin/blog/80345

阅读(7453) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~