shithub: openh264

Download patch

ref: 0a73155bdd4baeace8fe1514683aa4bfbf0f2382
parent: f7758a3074fdca930fd5732accb7ab08692a05b0
parent: bcf29e5b9fed0e332f7b2f77a20165c425acd610
author: Ethan Hugg <[email protected]>
date: Wed Feb 19 04:59:25 EST 2014

Merge pull request #306 from licaiguo/add-android-pull-clean

Add android Support

--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-UNAME=$(shell uname | tr A-Z a-z | tr -d \\-[:digit:].)
+OS=$(shell uname | tr A-Z a-z | tr -d \\-[:digit:].)
 ARCH=$(shell uname -m)
 LIBPREFIX=lib
 LIBSUFFIX=a
@@ -8,18 +8,10 @@
 LINK_LIB=-l$(1)
 CFLAGS_OPT=-O3
 CFLAGS_DEBUG=-g
-CFLAGS_M32=-m32
-CFLAGS_M64=-m64
 BUILDTYPE=Release
 V=Yes
 PREFIX=/usr/local
 
-ifeq (, $(ENABLE64BIT))
-ifeq ($(ARCH), x86_64)
-ENABLE64BIT=Yes
-endif
-endif
-
 ifeq (,$(wildcard ./gtest))
 HAVE_GTEST=No
 else
@@ -40,25 +32,11 @@
 LDFLAGS += -fsanitize=address
 endif
 
-ifeq ($(ENABLE64BIT), Yes)
-CFLAGS += $(CFLAGS_M64)
-LDFLAGS += $(CFLAGS_M64)
-ASMFLAGS_PLATFORM = -DUNIX64
-else
-CFLAGS += $(CFLAGS_M32)
-LDFLAGS += $(CFLAGS_M32)
-ASMFLAGS_PLATFORM = -DX86_32
-endif
+include build/platform-$(OS).mk
 
-include build/platform-$(UNAME).mk
 
-ifeq ($(USE_ASM),Yes)
-CFLAGS += -DX86_ASM
-endif
-
 CFLAGS += -DNO_DYNAMIC_VP
 LDFLAGS +=
-ASMFLAGS += $(ASMFLAGS_PLATFORM) -DNO_DYNAMIC_VP
 
 
 #### No user-serviceable parts below this line
@@ -129,15 +107,25 @@
 include codec/decoder/targets.mk
 include codec/encoder/targets.mk
 include codec/processing/targets.mk
+
+ifneq (android, $(OS))
 include codec/console/dec/targets.mk
 include codec/console/enc/targets.mk
+endif
 
-libraries: $(LIBPREFIX)wels.$(LIBSUFFIX)
-LIBRARIES += $(LIBPREFIX)wels.$(LIBSUFFIX)
+libraries: $(LIBPREFIX)wels.$(LIBSUFFIX) $(LIBPREFIX)wels.$(SHAREDLIBSUFFIX)
+LIBRARIES += $(LIBPREFIX)wels.$(LIBSUFFIX) $(LIBPREFIX)wels.$(SHAREDLIBSUFFIX)
 
 $(LIBPREFIX)wels.$(LIBSUFFIX): $(ENCODER_OBJS) $(DECODER_OBJS) $(PROCESSING_OBJS) $(COMMON_OBJS)
 	$(QUIET)rm -f $@
 	$(QUIET_AR)$(AR) $(AR_OPTS) $+
+
+$(LIBPREFIX)wels.$(SHAREDLIBSUFFIX): $(ENCODER_OBJS) $(DECODER_OBJS) $(PROCESSING_OBJS) $(COMMON_OBJS)
+	rm -f $@
+	@echo
+	@echo $+
+	@echo
+	$(CXX) -shared $(LDFLAGS) -o $@ $+
 
 install: $(LIBPREFIX)wels.$(LIBSUFFIX)
 	mkdir -p $(PREFIX)/lib
--- a/README.md
+++ b/README.md
@@ -38,7 +38,7 @@
 - Windows 64-bit and 32-bit
 - Mac OS X 64-bit and 32-bit
 - Linux 64-bit and 32-bit
-- Android 32-bit (initial release does not include this target, will follow soon)
+- Android 32-bit
 - iOS 64-bit and 32-bit (not supported yet, may be added in the future)
 
 Processor Support
@@ -51,6 +51,17 @@
 --------------------
 NASM needed to be installed for assembly code: workable version 2.07 or above, nasm can downloaded from http://www.nasm.us/
 
+For Android Builds
+------------------
+To build for android platform, You need to install android sdk and ndk. You also need to export <ANDROID_SDK>/tools to PATH. On Linux, this can be done by
+'export PATH=<ANDROID_SDK>/tools:$PATH'
+The codec and demo can be built by
+'make OS=android NDKROOT=<ANDROID_NDK>'
+You can also set ARCH, APILEVEL, GCCVERSION according to your device and NDK version.
+ARCH specifies the architecture of android device. Currently only arm and x86 are supported, the default is arm.
+APILEVEL specifies android api level, the api level can be 12-19, the default is 19.
+GCCVERSION specifies which gcc in NDK is used, the default is 4.8.
+
 For Windows Builds
 ------------------
 
@@ -67,7 +78,7 @@
 export INCLUDE="C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include;C:\Program Files (x86)\Windows Kits\8.0\Include\um;C:\Program Files (x86)\Windows Kits\8.0\Include\shared"
 export LIB="C:\Program Files (x86)\Windows Kits\8.0\Lib\Win8\um\x86;C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\lib"
 
-Then add 'UNAME=msvc' to the make line of the 'For All Platforms' instructions.
+Then add 'OS=msvc' to the make line of the 'For All Platforms' instructions.
 
 For All Platforms
 -------------------
--- /dev/null
+++ b/build/platform-android.mk
@@ -1,0 +1,35 @@
+USE_ASM = No
+ARCH = arm
+SHAREDLIBSUFFIX = so
+GCCVERSION = 4.8
+APILEVEL = 19
+HOSTOS = $(shell uname | tr A-Z a-z | tr -d \\-[:digit:].)
+HOSTARCH = $(shell uname -m)
+ifeq ($(ARCH), arm)
+    GCCPATHPREFIX = arm-linux-androideabi
+    GCCPREFIX = arm-linux-androideabi
+    CFLAGS += -march=armv7-a -mfloat-abi=softfp
+ifeq (Yes, $(HAVE_NEON))
+    CFLAGS += -mfpu=neon
+endif
+    LDFLAGS += -march=armv7-a -Wl,--fix-cortex-a8
+    APP_ABI = armeabi-v7a
+else
+    GCCPATHPREFIX = x86
+    GCCPREFIX = i686-linux-android
+    APP_ABI = x86
+endif
+
+SYSROOT = $(NDKROOT)/platforms/android-$(APILEVEL)/arch-$(ARCH)
+CXX = $(NDKROOT)/toolchains/$(GCCPATHPREFIX)-$(GCCVERSION)/prebuilt/$(HOSTOS)-$(HOSTARCH)/bin/$(GCCPREFIX)-g++
+CFLAGS += -DLINUX -fpic --sysroot=$(SYSROOT) -fno-rtti -fno-exceptions
+LDFLAGS += --sysroot=$(SYSROOT) -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,-soname,libwels.so
+
+
+binaries : decdemo encdemo
+
+decdemo: libraries
+	sh -c 'cd ./codec/build/android/dec/jni; $(NDKROOT)/ndk-build -B APP_ABI=$(APP_ABI); cd ..; android update project -p . ; ant debug; cd ../../../..'
+
+encdemo: libraries
+	sh -c 'cd ./codec/build/android/enc/jni; $(NDKROOT)/ndk-build -B APP_ABI=$(APP_ABI); cd ..; android update project -p . ; ant debug; cd ../../../..'
--- a/build/platform-darwin.mk
+++ b/build/platform-darwin.mk
@@ -1,5 +1,6 @@
-
+include build/platform-x86-common.mk
 ASM = nasm
+SHAREDLIBSUFFIX = dylib
 CFLAGS += -Wno-deprecated-declarations -Werror -fPIC -DMACOS -DMT_ENABLED -MMD -MP
 LDFLAGS += -lpthread
 ASMFLAGS += --prefix _ -DNOPREFIX
--- a/build/platform-freebsd.mk
+++ b/build/platform-freebsd.mk
@@ -1,4 +1,6 @@
+include build/platform-x86-common.mk
 ASM = nasm
+SHAREDLIBSUFFIX = so
 CFLAGS += -fPIC -DMT_ENABLED
 LDFLAGS += -lpthread
 ASMFLAGS += -DNOPREFIX
--- a/build/platform-linux.mk
+++ b/build/platform-linux.mk
@@ -1,4 +1,6 @@
+include build/platform-x86-common.mk
 ASM = nasm
+SHAREDLIBSUFFIX = so
 CFLAGS += -Werror -fPIC -DLINUX -DMT_ENABLED -MMD -MP
 LDFLAGS += -lpthread
 ASMFLAGS += -DNOPREFIX
--- a/build/platform-mingw_nt.mk
+++ b/build/platform-mingw_nt.mk
@@ -1,4 +1,6 @@
+include build/platform-x86-common.mk
 ASM = nasm
+SHAREDLIBSUFFIX = dll
 CFLAGS += -DMT_ENABLED -MMD -MP
 LDFLAGS +=
 ifeq ($(ENABLE64BIT), Yes)
--- /dev/null
+++ b/build/platform-x86-common.mk
@@ -1,0 +1,20 @@
+CFLAGS_M32=-m32
+CFLAGS_M64=-m64
+ifeq (, $(ENABLE64BIT))
+ifeq ($(ARCH), x86_64)
+ENABLE64BIT=Yes
+endif
+endif
+ifeq ($(ENABLE64BIT), Yes)
+CFLAGS += $(CFLAGS_M64)
+LDFLAGS += $(CFLAGS_M64)
+ASMFLAGS_PLATFORM = -DUNIX64
+else
+CFLAGS += $(CFLAGS_M32)
+LDFLAGS += $(CFLAGS_M32)
+ASMFLAGS_PLATFORM = -DX86_32
+endif
+ifeq ($(USE_ASM),Yes)
+CFLAGS += -DX86_ASM
+endif
+ASMFLAGS += $(ASMFLAGS_PLATFORM) -DNO_DYNAMIC_VP
--- /dev/null
+++ b/codec/build/android/dec/AndroidManifest.xml
@@ -1,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+      package="com.wels.dec"
+      android:versionCode="1"
+      android:versionName="1.0">
+<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
+    <application android:icon="@drawable/icon" android:label="@string/app_name">
+        <activity android:name=".WelsDecTest"
+                  android:label="@string/app_name">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+
+    </application>
+
+
+</manifest> 
\ No newline at end of file
--- /dev/null
+++ b/codec/build/android/dec/jni/Android.mk
@@ -1,0 +1,14 @@
+## yongzxu: refine mk files for android platform
+
+#To fix the bug that Intel NDK can't creat directory
+$(shell mkdir -p $(TARGET_OBJS)/cpufeatures)
+$(shell mkdir -p $(TARGET_OBJS)/welsdecdemo)
+
+LOCAL_PATH := $(call my-dir)
+MY_LOCAL_PATH := $(LOCAL_PATH)
+
+# Step3
+#Generate the libwelsdecdemo.so file
+include $(LOCAL_PATH)/welsdecdemo.mk
+LOCAL_PATH := $(MY_LOCAL_PATH)
+
--- /dev/null
+++ b/codec/build/android/dec/jni/Application.mk
@@ -1,0 +1,21 @@
+# debug/release, default is release
+ifeq ($(OPTIM_debug),true)
+APP_OPTIM := debug
+else
+APP_OPTIM := release
+endif
+
+# x86/armeabi-v7a/armeabi, default is armeabi-v7a
+ifeq ($(ABI_x86),true)
+APP_ABI := x86
+else
+ifeq ($(ABI_armeabi),true)
+APP_ABI := armeabi
+else
+APP_ABI := armeabi-v7a
+endif
+endif
+
+APP_STL := stlport_shared
+#APP_STL := gnustl_shared
+APP_PLATFORM := android-12
--- /dev/null
+++ b/codec/build/android/dec/jni/myjni.cpp
@@ -1,0 +1,24 @@
+#include <string.h>
+#include <stdlib.h>
+#include <jni.h>
+#include <android/log.h>
+
+#define LOG_TAG "welsdec"
+#define LOGI(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
+
+extern int DecMain (int argc, char* argv[]);
+extern "C"
+JNIEXPORT void JNICALL Java_com_wels_dec_WelsDecTest_DoDecoderTest
+(JNIEnv* env, jobject thiz, jstring jsFileNameIn, jstring jsFileNameOut) {
+  /**************** Add the native codes/API *****************/
+  char* argv[3];
+  int  argc = 3;
+  argv[0] = (char*) ("decConsole.exe");
+  argv[1] = (char*) ((*env).GetStringUTFChars (jsFileNameIn, NULL));
+  argv[2] = (char*) ((*env).GetStringUTFChars (jsFileNameOut, NULL));
+  LOGI ("Start to run JNI module!+++");
+  DecMain (argc, argv);
+  LOGI ("End to run JNI module!+++");
+}
+
+
--- /dev/null
+++ b/codec/build/android/dec/jni/welsdecdemo.mk
@@ -1,0 +1,56 @@
+# Generate the libwelsdecdemo.so file
+LOCAL_PATH := $(call my-dir)
+
+#include $(CLEAR_VARS)
+#LOCAL_MODULE := stlport
+#LOCAL_SRC_FILES := $(NDK_ROOT)/sources/cxx-stl/stlport/libs/$(TARGET_ARCH_ABI)/libstlport_static.a
+#LOCAL_EXPORT_C_INCLUDES := $(NDK_ROOT)/sources/cxx-stl/stlport/stlport
+#include $(PREBUILT_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE    := wels
+LOCAL_SRC_FILES := $(LOCAL_PATH)/../../../../../libwels.so
+include $(PREBUILT_SHARED_LIBRARY)
+
+
+
+include $(CLEAR_VARS)
+
+#
+# Module Settings
+#
+LOCAL_MODULE := welsdecdemo
+
+#
+# Source Files
+#
+CODEC_PATH := ../../../../
+CONSOLE_DEC_PATH := ../../../../console/dec
+LOCAL_SRC_FILES := \
+            $(CONSOLE_DEC_PATH)/src/h264dec.cpp \
+            $(CONSOLE_DEC_PATH)/src/read_config.cpp \
+            $(CONSOLE_DEC_PATH)/src/d3d9_utils.cpp \
+            $(CODEC_PATH)/common/logging.cpp \
+            myjni.cpp
+#
+# Header Includes
+#
+LOCAL_C_INCLUDES := \
+            $(LOCAL_PATH)/../../../../api/svc \
+            $(LOCAL_PATH)/../../../../console/dec/inc \
+            $(LOCAL_PATH)/../../../../common
+#
+# Compile Flags and Link Libraries
+#
+LOCAL_CFLAGS := -O3 -DANDROID_NDK
+
+ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
+LOCAL_ARM_MODE := arm
+endif
+
+#LOCAL_STATIC_LIBRARIES += stlport
+LOCAL_LDLIBS := -llog
+#LOCAL_LDLIBS += -L../../../ -lwels
+LOCAL_SHARED_LIBRARIES := wels
+
+include $(BUILD_SHARED_LIBRARY)
--- /dev/null
+++ b/codec/build/android/dec/proguard.cfg
@@ -1,0 +1,40 @@
+-optimizationpasses 5
+-dontusemixedcaseclassnames
+-dontskipnonpubliclibraryclasses
+-dontpreverify
+-verbose
+-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
+
+-keep public class * extends android.app.Activity
+-keep public class * extends android.app.Application
+-keep public class * extends android.app.Service
+-keep public class * extends android.content.BroadcastReceiver
+-keep public class * extends android.content.ContentProvider
+-keep public class * extends android.app.backup.BackupAgentHelper
+-keep public class * extends android.preference.Preference
+-keep public class com.android.vending.licensing.ILicensingService
+
+-keepclasseswithmembernames class * {
+    native <methods>;
+}
+
+-keepclasseswithmembers class * {
+    public <init>(android.content.Context, android.util.AttributeSet);
+}
+
+-keepclasseswithmembers class * {
+    public <init>(android.content.Context, android.util.AttributeSet, int);
+}
+
+-keepclassmembers class * extends android.app.Activity {
+   public void *(android.view.View);
+}
+
+-keepclassmembers enum * {
+    public static **[] values();
+    public static ** valueOf(java.lang.String);
+}
+
+-keep class * implements android.os.Parcelable {
+  public static final android.os.Parcelable$Creator *;
+}
--- /dev/null
+++ b/codec/build/android/dec/project.properties
@@ -1,0 +1,14 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+# Project target.
+target=android-12
binary files /dev/null b/codec/build/android/dec/res/drawable-hdpi/icon.png differ
binary files /dev/null b/codec/build/android/dec/res/drawable-ldpi/icon.png differ
--- /dev/null
+++ b/codec/build/android/dec/res/layout/main.xml
@@ -1,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:orientation="vertical" >
+	<LinearLayout
+	    android:layout_width="wrap_content"
+	    android:layout_height="wrap_content"
+	    android:orientation="horizontal">"
+	    <Button
+	        android:id="@+id/cfg"
+	        android:layout_width="wrap_content"
+	        android:layout_height="wrap_content"
+	        android:text="Load bitstreams" />
+	    <Button
+	        android:id="@+id/buttonSW"
+	        android:layout_width="wrap_content"
+	        android:layout_height="wrap_content"
+	        android:text="Test" />
+		</LinearLayout>
+</LinearLayout>
--- /dev/null
+++ b/codec/build/android/dec/res/values/strings.xml
@@ -1,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="app_name">WelsDecoderTest</string>
+</resources>
--- /dev/null
+++ b/codec/build/android/dec/src/com/wels/dec/WelsDecTest.java
@@ -1,0 +1,117 @@
+package com.wels.dec;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.Environment;
+import android.util.Log;
+
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.View.OnClickListener;
+
+import android.widget.Button;
+import android.widget.TextView;
+import java.io.*;
+import java.util.Vector;
+
+public class WelsDecTest extends Activity {
+    /** Called when the activity is first created. */
+    private OnClickListener OnClickEvent;
+    private Button mBtnLoad, mBtnStartSW;
+
+    final String   mStreamPath = "/sdcard/wels-seq/";
+    Vector<String> mStreamFiles = new Vector<String>();
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        final TextView  tv = new TextView(this);
+        System.out.println("Here we go ...");
+        Log.i(TAG, "sdcard path:" + Environment.getExternalStorageDirectory().getAbsolutePath());
+        setContentView(R.layout.main);
+
+        mBtnLoad = (Button)findViewById(R.id.cfg);
+        mBtnStartSW = (Button)findViewById(R.id.buttonSW);
+
+        OnClickEvent = new OnClickListener()
+        {
+            public void onClick(View v)
+            {
+                switch(v.getId())
+                {
+                case R.id.cfg:
+                {
+                    String cfgFile = mStreamPath + "BitStreams.txt";
+                    try {
+                        BufferedReader bufferedReader = new BufferedReader(new FileReader(cfgFile));
+                        String text;
+                        while((text = bufferedReader.readLine()) != null) {
+                            mStreamFiles.add(mStreamPath + text);
+                            Log.i(TAG, mStreamPath + text);
+                        }
+                        bufferedReader.close();
+                    } catch(IOException e) {
+                        Log.e("WELS_DEC", e.getMessage());
+                    }
+                }
+                break;
+                case R.id.buttonSW:
+                {
+                    System.out.println("decode sequence number = " + mStreamFiles.size());
+                    Log.i("WSE_DEC","after click");
+                    try {
+                        for (int k=0; k < mStreamFiles.size(); k++) {
+                            String inFile =  mStreamFiles.get(k);
+                            String outFile =  mStreamFiles.get(k) + ".yuv";
+                            Log.i(TAG, "input file:" + inFile+ "    output file:" + outFile);
+                            DoDecoderTest(inFile, outFile);
+                        }
+                    } catch (Exception e) {
+                        Log.e(TAG, e.getMessage());
+                    }
+                    mStreamFiles.clear();
+                    tv.setText( "Decoder is completed!" );
+                }
+                break;
+                }
+            }
+        };
+
+        mBtnLoad.setOnClickListener(OnClickEvent);
+        mBtnStartSW.setOnClickListener(OnClickEvent);
+
+        System.out.println("Done!");
+    }
+
+    @Override
+    public void onStart()
+    {
+        Log.i("WSE_DEC","welsdecdemo onStart");
+        super.onStart();
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        switch (keyCode) {
+        case KeyEvent.KEYCODE_BACK:
+            return true;
+        default:
+            return super.onKeyDown(keyCode, event);
+        }
+    }
+
+    public native void  DoDecoderTest(String infilename, String outfilename);
+    private static final String TAG = "welsdec";
+    static {
+        try {
+            System.loadLibrary("wels");
+            System.loadLibrary("stlport_shared");
+            System.loadLibrary("welsdecdemo");
+            Log.v(TAG, "Load libwelsdec successful");
+        }
+        catch(Exception e) {
+            Log.e(TAG, "Failed to load welsdec"+e.getMessage());
+        }
+    }
+}
+
--- /dev/null
+++ b/codec/build/android/enc/AndroidManifest.xml
@@ -1,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+      package="com.wels.enc"
+      android:versionCode="1"
+      android:versionName="1.0">
+<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
+    <application android:icon="@drawable/icon" android:label="@string/app_name">
+        <activity android:name=".WelsEncTest"
+                  android:label="@string/app_name">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+
+    </application>
+
+
+</manifest> 
\ No newline at end of file
--- /dev/null
+++ b/codec/build/android/enc/jni/Android.mk
@@ -1,0 +1,14 @@
+## yongzxu: refine mk files for android platform
+
+#To fix the bug that Intel NDK can't creat directory
+$(shell mkdir -p $(TARGET_OBJS)/cpufeatures)
+$(shell mkdir -p $(TARGET_OBJS)/welsdecdemo)
+
+LOCAL_PATH := $(call my-dir)
+MY_LOCAL_PATH := $(LOCAL_PATH)
+
+# Step3
+#Generate the libwelsdecdemo.so file
+include $(LOCAL_PATH)/welsencdemo.mk
+LOCAL_PATH := $(MY_LOCAL_PATH)
+
--- /dev/null
+++ b/codec/build/android/enc/jni/Application.mk
@@ -1,0 +1,21 @@
+# debug/release, default is release
+ifeq ($(OPTIM_debug),true)
+APP_OPTIM := debug
+else
+APP_OPTIM := release
+endif
+
+# x86/armeabi-v7a/armeabi, default is armeabi-v7a
+ifeq ($(ABI_x86),true)
+APP_ABI := x86
+else
+ifeq ($(ABI_armeabi),true)
+APP_ABI := armeabi
+else
+APP_ABI := armeabi-v7a
+endif
+endif
+
+APP_STL := stlport_shared
+#APP_STL := gnustl_shared
+APP_PLATFORM := android-12
--- /dev/null
+++ b/codec/build/android/enc/jni/myjni.cpp
@@ -1,0 +1,24 @@
+#include <string.h>
+#include <stdlib.h>
+#include <jni.h>
+#include <android/log.h>
+
+#define LOG_TAG "welsdec"
+#define LOGI(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
+
+extern int EncMain (int argc, char* argv[]);
+extern "C"
+JNIEXPORT void JNICALL Java_com_wels_enc_WelsEncTest_DoEncoderTest
+(JNIEnv* env, jobject thiz, jstring jsFileNameIn) {
+  /**************** Add the native codes/API *****************/
+  char* argv[2];
+  int  argc = 2;
+  argv[0] = (char*) ("decConsole.exe");
+  argv[1] = (char*) ((*env).GetStringUTFChars (jsFileNameIn, NULL));
+  LOGI ("Start to run JNI module!+++");
+  EncMain (argc, argv);
+  LOGI ("End to run JNI module!+++");
+
+}
+
+
--- /dev/null
+++ b/codec/build/android/enc/jni/welsencdemo.mk
@@ -1,0 +1,59 @@
+# Generate the libwelsdecdemo.so file
+LOCAL_PATH := $(call my-dir)
+
+#include $(CLEAR_VARS)
+#LOCAL_MODULE := stlport
+#LOCAL_SRC_FILES := $(NDK_ROOT)/sources/cxx-stl/stlport/libs/$(TARGET_ARCH_ABI)/libstlport_static.a
+#LOCAL_EXPORT_C_INCLUDES := $(NDK_ROOT)/sources/cxx-stl/stlport/stlport
+#include $(PREBUILT_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE    := wels
+LOCAL_SRC_FILES := $(LOCAL_PATH)/../../../../../libwels.so
+include $(PREBUILT_SHARED_LIBRARY)
+
+
+
+include $(CLEAR_VARS)
+
+#
+# Module Settings
+#
+LOCAL_MODULE := welsencdemo
+
+#
+# Source Files
+#
+CODEC_PATH := ../../../../
+CONSOLE_ENC_PATH := ../../../../console/enc
+LOCAL_SRC_FILES := \
+            $(CONSOLE_ENC_PATH)/src/welsenc.cpp \
+            $(CONSOLE_ENC_PATH)/src/read_config.cpp \
+            $(CODEC_PATH)/common/logging.cpp \
+            myjni.cpp
+
+#
+# Header Includes
+#
+LOCAL_C_INCLUDES := \
+            $(LOCAL_PATH)/../../../../api/svc \
+            $(LOCAL_PATH)/../../../../console/enc/inc \
+            $(LOCAL_PATH)/../../../../encoder/core/inc \
+            $(LOCAL_PATH)/../../../../common
+
+  
+#
+# Compile Flags and Link Libraries
+#
+LOCAL_CFLAGS := -O3 -DANDROID_NDK
+
+ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
+LOCAL_ARM_MODE := arm
+endif
+
+#LOCAL_STATIC_LIBRARIES += stlport
+LOCAL_LDLIBS := -llog
+#LOCAL_LDLIBS += -L../../../ -lwels
+LOCAL_SHARED_LIBRARIES := wels
+
+include $(BUILD_SHARED_LIBRARY)
--- /dev/null
+++ b/codec/build/android/enc/proguard.cfg
@@ -1,0 +1,40 @@
+-optimizationpasses 5
+-dontusemixedcaseclassnames
+-dontskipnonpubliclibraryclasses
+-dontpreverify
+-verbose
+-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
+
+-keep public class * extends android.app.Activity
+-keep public class * extends android.app.Application
+-keep public class * extends android.app.Service
+-keep public class * extends android.content.BroadcastReceiver
+-keep public class * extends android.content.ContentProvider
+-keep public class * extends android.app.backup.BackupAgentHelper
+-keep public class * extends android.preference.Preference
+-keep public class com.android.vending.licensing.ILicensingService
+
+-keepclasseswithmembernames class * {
+    native <methods>;
+}
+
+-keepclasseswithmembers class * {
+    public <init>(android.content.Context, android.util.AttributeSet);
+}
+
+-keepclasseswithmembers class * {
+    public <init>(android.content.Context, android.util.AttributeSet, int);
+}
+
+-keepclassmembers class * extends android.app.Activity {
+   public void *(android.view.View);
+}
+
+-keepclassmembers enum * {
+    public static **[] values();
+    public static ** valueOf(java.lang.String);
+}
+
+-keep class * implements android.os.Parcelable {
+  public static final android.os.Parcelable$Creator *;
+}
--- /dev/null
+++ b/codec/build/android/enc/project.properties
@@ -1,0 +1,14 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+# Project target.
+target=android-12
binary files /dev/null b/codec/build/android/enc/res/drawable-hdpi/icon.png differ
binary files /dev/null b/codec/build/android/enc/res/drawable-ldpi/icon.png differ
--- /dev/null
+++ b/codec/build/android/enc/res/layout/main.xml
@@ -1,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:orientation="vertical" >
+	<LinearLayout
+	    android:layout_width="wrap_content"
+	    android:layout_height="wrap_content"
+	    android:orientation="horizontal">"
+	    <Button
+	        android:id="@+id/cfg"
+	        android:layout_width="wrap_content"
+	        android:layout_height="wrap_content"
+	        android:text="Load bitstreams" />
+	    <Button
+	        android:id="@+id/buttonSW"
+	        android:layout_width="wrap_content"
+	        android:layout_height="wrap_content"
+	        android:text="Test" />
+		</LinearLayout>
+</LinearLayout>
--- /dev/null
+++ b/codec/build/android/enc/res/values/strings.xml
@@ -1,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="app_name">WelsEncoderTest</string>
+</resources>
--- /dev/null
+++ b/codec/build/android/enc/src/com/wels/enc/WelsEncTest.java
@@ -1,0 +1,118 @@
+package com.wels.enc;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.Environment;
+import android.util.Log;
+
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.View.OnClickListener;
+
+import android.widget.Button;
+import android.widget.TextView;
+import java.io.*;
+import java.util.Vector;
+
+public class WelsEncTest extends Activity {
+    /** Called when the activity is first created. */
+    private OnClickListener OnClickEvent;
+    private Button mBtnLoad, mBtnStartSW;
+
+    final String   mStreamPath = "/sdcard/wels-seq/";
+    Vector<String> mCfgFiles = new Vector<String>();
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        final TextView  tv = new TextView(this);
+        System.out.println("Here we go ...");
+        Log.i(TAG, "sdcard path:" + Environment.getExternalStorageDirectory().getAbsolutePath());
+        setContentView(R.layout.main);
+
+        mBtnLoad = (Button)findViewById(R.id.cfg);
+        mBtnStartSW = (Button)findViewById(R.id.buttonSW);
+
+
+        OnClickEvent = new OnClickListener()
+        {
+            public void onClick(View v)
+            {
+                switch(v.getId())
+                {
+                case R.id.cfg:
+                {
+                    String cfgFile = mStreamPath + "cfgs.txt";
+                    try {
+                        BufferedReader bufferedReader = new BufferedReader(new FileReader(cfgFile));
+                        String text;
+                        while((text = bufferedReader.readLine()) != null) {
+                            mCfgFiles.add(mStreamPath + text);
+                            Log.i(TAG, mStreamPath + text);
+                        }
+                        bufferedReader.close();
+                    } catch(IOException e) {
+                        Log.e(TAG, e.getMessage());
+                    }
+                }
+                break;
+                case R.id.buttonSW:
+                {
+                    System.out.println("decode sequence number = " + mCfgFiles.size());
+                    Log.i(TAG,"after click");
+                    try {
+                        for (int k=0; k < mCfgFiles.size(); k++) {
+                            String cfgFile =  mCfgFiles.get(k);
+                            DoEncoderTest(cfgFile);
+                        }
+                    } catch (Exception e) {
+                        Log.e(TAG, e.getMessage());
+                    }
+                    mCfgFiles.clear();
+                    tv.setText( "Decoder is completed!" );
+                }
+                break;
+                }
+            }
+        };
+
+        mBtnLoad.setOnClickListener(OnClickEvent);
+        mBtnStartSW.setOnClickListener(OnClickEvent);
+
+        System.out.println("Done!");
+    }
+
+    @Override
+    public void onStart()
+    {
+        Log.i(TAG,"welsdecdemo onStart");
+        super.onStart();
+    }
+
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        switch (keyCode) {
+        case KeyEvent.KEYCODE_BACK:
+            return true;
+        default:
+            return super.onKeyDown(keyCode, event);
+        }
+    }
+
+    public native void  DoEncoderTest(String cfgFileName);
+    private static final String TAG = "welsenc";
+    static {
+        try {
+            System.loadLibrary("wels");
+            System.loadLibrary("stlport_shared");
+            System.loadLibrary("welsencdemo");
+            Log.v(TAG, "Load libwelsencdemo.so successful");
+        }
+        catch(Exception e) {
+            Log.e(TAG, "Failed to load welsdec"+e.getMessage());
+        }
+    }
+
+}
+
--- a/codec/console/dec/src/h264dec.cpp
+++ b/codec/console/dec/src/h264dec.cpp
@@ -40,7 +40,9 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdarg.h>
-
+#if defined (ANDROID_NDK)
+#include <android/log.h>
+#endif
 #include "codec_def.h"
 #include "codec_app_def.h"
 #include "codec_api.h"
@@ -52,7 +54,12 @@
 
 
 using namespace std;
-
+#if defined(ANDROID_NDK)
+#define LOG_TAG "welsdec"
+#define LOGI(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
+#define printf LOGI
+#define fprintf(a, ...) LOGI(__VA_ARGS__)
+#endif
 //using namespace WelsDec;
 
 //#define STICK_STREAM_SIZE	// For Demo interfaces test with track file of integrated frames
@@ -292,8 +299,11 @@
   }
 }
 
-
+#if defined(ANDROID_NDK)
+int32_t DecMain(int32_t iArgC, char* pArgV[]) {
+#else
 int32_t main (int32_t iArgC, char* pArgV[]) {
+#endif
   ISVCDecoder* pDecoder = NULL;
 
   SDecodingParam sDecParam = {0};
--- a/codec/console/enc/src/welsenc.cpp
+++ b/codec/console/enc/src/welsenc.cpp
@@ -35,14 +35,20 @@
 #include <assert.h>
 #include <signal.h>
 #include <stdarg.h>
-
+#if defined (ANDROID_NDK)
+#include <android/log.h>
+#endif
 #ifdef ONLY_ENC_FRAMES_NUM
 #undef ONLY_ENC_FRAMES_NUM
 #endif//ONLY_ENC_FRAMES_NUM
 #define ONLY_ENC_FRAMES_NUM		INT_MAX // 2, INT_MAX	// type the num you try to encode here, 2, 10, etc
 
-
-
+#if defined (ANDROID_NDK)
+#define LOG_TAG "welsenc"
+#define LOGI(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
+#define printf(...) LOGI(__VA_ARGS__)
+#define fprintf(a, ...) LOGI(__VA_ARGS__)
+#endif
 //#define STICK_STREAM_SIZE
 
 #include "measure_time.h"
@@ -1217,7 +1223,11 @@
 /****************************************************************************
  * main:
  ****************************************************************************/
+#if defined(ANDROID_NDK)
+int EncMain(int argc, char **argv)
+#else
 int main (int argc, char** argv)
+#endif
 {
   ISVCEncoder* pSVCEncoder	= NULL;
   int iRet					= 0;