Add a new android application example.

The features of this example are:
1. Allow choosing video source from filesystem.
2. Allow choosing audio source from filesystem.
3. Allow configuring video encoder parameters.
4. Allow configuring audio encoder parameters.
5. Allow playing back the encoded WebM file.

Change-Id: I078bc950ed4185a1dce41b015a32f7c7e534f8c9
diff --git a/JNI/examples/bindingEncodeExample/.classpath b/JNI/examples/bindingEncodeExample/.classpath
new file mode 100644
index 0000000..a4763d1
--- /dev/null
+++ b/JNI/examples/bindingEncodeExample/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="src" path="gen"/>
+	<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
+	<classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
+	<classpathentry kind="output" path="bin/classes"/>
+</classpath>
diff --git a/JNI/examples/bindingEncodeExample/.project b/JNI/examples/bindingEncodeExample/.project
new file mode 100644
index 0000000..e77e3b2
--- /dev/null
+++ b/JNI/examples/bindingEncodeExample/.project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>bindingEncodeExample</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>com.android.ide.eclipse.adt.ApkBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/JNI/examples/bindingEncodeExample/AndroidManifest.xml b/JNI/examples/bindingEncodeExample/AndroidManifest.xml
new file mode 100644
index 0000000..9ed3400
--- /dev/null
+++ b/JNI/examples/bindingEncodeExample/AndroidManifest.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.bindingEncodeExample"
+    android:versionCode="1"
+    android:versionName="1.0" >
+
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
+    <uses-sdk
+        android:minSdkVersion="8"
+        android:targetSdkVersion="17" />
+
+    <application
+        android:allowBackup="true"
+        android:debuggable="true"
+        android:icon="@drawable/ic_launcher"
+        android:label="@string/app_name"
+        android:theme="@style/AppTheme" >
+        <activity
+            android:name="com.example.bindingEncodeExample.MainActivity"
+            android:label="@string/app_name" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity
+            android:name=".VideoEncoderSettingDialog"
+            android:label="Video Encode Config"
+            android:theme="@android:style/Theme.Dialog" >
+        </activity>
+        <activity
+            android:name=".AudioEncoderSettingDialog"
+            android:label="Audio Encode Config"
+            android:theme="@android:style/Theme.Dialog" >
+        </activity>
+        <activity
+            android:name=".FileExplorer"
+            android:theme="@android:style/Theme.Dialog" >
+        </activity>
+    </application>
+
+</manifest>
\ No newline at end of file
diff --git a/JNI/examples/bindingEncodeExample/AppScreenShot.png b/JNI/examples/bindingEncodeExample/AppScreenShot.png
new file mode 100644
index 0000000..f7f44b6
--- /dev/null
+++ b/JNI/examples/bindingEncodeExample/AppScreenShot.png
Binary files differ
diff --git a/JNI/examples/bindingEncodeExample/README b/JNI/examples/bindingEncodeExample/README
new file mode 100644
index 0000000..339d8ee
--- /dev/null
+++ b/JNI/examples/bindingEncodeExample/README
@@ -0,0 +1,46 @@
+/*
+* This project is an Android application example showing how to use WebM jni bindings to encode video.
+* This app allows you choose video and audio source files, configure different video and audio encoding parameters.
+* You could set up your eclipse project following the below steps.
+*/
+
+# Add the JNI code.
+1. cd to jni folder.
+
+# Get JNI bindings
+2. git clone http://git.chromium.org/webm/bindings.git
+
+# Get libvpx
+3. git clone http://git.chromium.org/webm/libvpx.git
+
+# Configure libvpx for Android
+4. ./libvpx/configure --target=armv7-android-gcc --disable-examples --sdk-path=<full path to>/<NDK>/android-ndk-r8e/
+
+5. cd bindings/JNI
+
+# Get libwebm
+6. git clone http://git.chromium.org/webm/libwebm.git
+
+# Get libogg
+7. Download ogg code from http://downloads.xiph.org/releases/ogg/libogg-1.3.0.tar.gz
+8. extract to bindings/JNI
+
+# We need to run configure to generate config_types.h.
+9. cd libogg-1.3.0 && ./configure && cd ..
+
+# Get libvorbis
+10. Download vorbis code from http://downloads.xiph.org/releases/vorbis/libvorbis-1.3.3.tar.gz
+11. extract to bindings/JNI
+
+# Get libyuv
+12. svn checkout http://libyuv.googlecode.com/svn/trunk/ libyuv-read-only
+
+13. cd ../..
+
+# Build the JNI code.
+14. ndk-build
+
+# Copy the java code.
+15. cp -R bindings/JNI/com/google ../src/com/
+
+16. Build the Android app now and run it on Android device.
diff --git a/JNI/examples/bindingEncodeExample/ic_launcher-web.png b/JNI/examples/bindingEncodeExample/ic_launcher-web.png
new file mode 100644
index 0000000..1fe51a9
--- /dev/null
+++ b/JNI/examples/bindingEncodeExample/ic_launcher-web.png
Binary files differ
diff --git a/JNI/examples/bindingEncodeExample/jni/Android.mk b/JNI/examples/bindingEncodeExample/jni/Android.mk
new file mode 100644
index 0000000..b8dbd32
--- /dev/null
+++ b/JNI/examples/bindingEncodeExample/jni/Android.mk
@@ -0,0 +1,3 @@
+WORKING_DIR := $(call my-dir)
+BINDINGS_DIR:=  $(WORKING_DIR)/bindings/JNI
+include $(BINDINGS_DIR)/Android.mk
diff --git a/JNI/examples/bindingEncodeExample/jni/Application.mk b/JNI/examples/bindingEncodeExample/jni/Application.mk
new file mode 100644
index 0000000..cc2e1e6
--- /dev/null
+++ b/JNI/examples/bindingEncodeExample/jni/Application.mk
@@ -0,0 +1,5 @@
+# Build ARMv7-A machine code.
+APP_ABI := armeabi-v7a
+APP_OPTIM := release
+APP_STL := gnustl_static
+APP_CPPFLAGS := -frtti
diff --git a/JNI/examples/bindingEncodeExample/libs/android-support-v4.jar b/JNI/examples/bindingEncodeExample/libs/android-support-v4.jar
new file mode 100644
index 0000000..65ebaf8
--- /dev/null
+++ b/JNI/examples/bindingEncodeExample/libs/android-support-v4.jar
Binary files differ
diff --git a/JNI/examples/bindingEncodeExample/proguard-project.txt b/JNI/examples/bindingEncodeExample/proguard-project.txt
new file mode 100644
index 0000000..f2fe155
--- /dev/null
+++ b/JNI/examples/bindingEncodeExample/proguard-project.txt
@@ -0,0 +1,20 @@
+# To enable ProGuard in your project, edit project.properties
+# to define the proguard.config property as described in that file.
+#
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in ${sdk.dir}/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
diff --git a/JNI/examples/bindingEncodeExample/project.properties b/JNI/examples/bindingEncodeExample/project.properties
new file mode 100644
index 0000000..a3ee5ab
--- /dev/null
+++ b/JNI/examples/bindingEncodeExample/project.properties
@@ -0,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-17
diff --git a/JNI/examples/bindingEncodeExample/res/drawable-hdpi/ic_launcher.png b/JNI/examples/bindingEncodeExample/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..ffa9f95
--- /dev/null
+++ b/JNI/examples/bindingEncodeExample/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/JNI/examples/bindingEncodeExample/res/drawable-mdpi/ic_launcher.png b/JNI/examples/bindingEncodeExample/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..6231509
--- /dev/null
+++ b/JNI/examples/bindingEncodeExample/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/JNI/examples/bindingEncodeExample/res/drawable-xhdpi/ic_launcher.png b/JNI/examples/bindingEncodeExample/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..ed9a37a
--- /dev/null
+++ b/JNI/examples/bindingEncodeExample/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/JNI/examples/bindingEncodeExample/res/drawable-xxhdpi/ic_launcher.png b/JNI/examples/bindingEncodeExample/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..f5bea96
--- /dev/null
+++ b/JNI/examples/bindingEncodeExample/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/JNI/examples/bindingEncodeExample/res/layout/activity_main.xml b/JNI/examples/bindingEncodeExample/res/layout/activity_main.xml
new file mode 100644
index 0000000..c721b39
--- /dev/null
+++ b/JNI/examples/bindingEncodeExample/res/layout/activity_main.xml
@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent" >
+
+    <TableLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="#ffffff"
+        android:shrinkColumns="*"
+        android:stretchColumns="*" >
+
+        <TableRow
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center_horizontal" >
+        </TableRow>
+
+        <TableRow android:gravity="center" >
+
+            <Button
+                android:id="@+id/videoSrcBtn"
+                style="@style/btn_bottommenu"
+                android:text="Video File Select(.y4m)" />
+
+            <TextView
+                android:id="@+id/videoSrcDisp"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:gravity="center"
+                android:text="No Input"
+                android:textColor="@color/text_color" >
+            </TextView>
+        </TableRow>
+
+        <TableRow>
+
+            <Button
+                android:id="@+id/audioSrcBtn"
+                style="@style/btn_bottommenu"
+                android:text="Auido File Select(.wav)" />
+
+            <TextView
+                android:id="@+id/audioSrcDisp"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:gravity="center"
+                android:text="No Input"
+                android:textColor="@color/text_color" >
+            </TextView>
+        </TableRow>
+
+        <TableRow>
+
+            <Button
+                android:id="@+id/outputDirBtn"
+                style="@style/btn_bottommenu"
+                android:text="File ouput name:" />
+
+            <TextView
+                android:id="@+id/fileOutputDisp"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:gravity="center"
+                android:text="/sdcard/media/out.webm"
+                android:textColor="@color/text_color" >
+            </TextView>
+        </TableRow>
+
+        <TableRow android:gravity="center" >
+
+            <Button
+                android:id="@+id/videoEncodeConfigBtn"
+                style="@style/btn_bottommenu"
+                android:text="Video Encode Config" />
+
+            <TextView
+                android:id="@+id/videoEncodeConfigDisp"
+                android:layout_width="352dip"
+                android:layout_height="wrap_content"
+                android:gravity="center"
+                android:text="No Config"
+                android:textColor="@color/text_color" >
+            </TextView>
+        </TableRow>
+
+        <TableRow android:gravity="center" >
+
+            <Button
+                android:id="@+id/audioEncodeConfigBtn"
+                style="@style/btn_bottommenu"
+                android:text="Audio Encode Config" />
+
+            <TextView
+                android:id="@+id/audioEncodeConfigDisp"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:gravity="center"
+                android:text="No Config"
+                android:textColor="@color/text_color" >
+            </TextView>
+        </TableRow>
+
+        <TableRow android:gravity="center" >
+
+            <Button
+                android:id="@+id/StartEncodeBtn"
+                style="@style/btn_bottommenu"
+                android:text="Start Encode" />
+
+            <TextView
+                android:id="@+id/EncodingStatsDisp"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:gravity="center"
+                android:text="Ready to encode"
+                android:textColor="@color/text_color" >
+            </TextView>
+        </TableRow>
+
+        <TableRow android:gravity="center" >
+
+            <Button
+                android:id="@+id/PlayVideoBtn"
+                style="@style/btn_bottommenu"
+                android:text="Play Encoded Video" />
+
+            <TextView
+                android:id="@+id/PlayingStatsDisp"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:gravity="center"
+                android:textColor="@color/text_color" >
+            </TextView>
+        </TableRow>
+
+        <SurfaceView
+            android:id="@+id/surface"
+            android:layout_width="352dip"
+            android:layout_height="288dip"
+            android:layout_below="@+id/PlayVideoBtn"
+            android:paddingTop="100dip" />
+    </TableLayout>
+
+</RelativeLayout>
diff --git a/JNI/examples/bindingEncodeExample/res/layout/alert_diag.xml b/JNI/examples/bindingEncodeExample/res/layout/alert_diag.xml
new file mode 100644
index 0000000..f60b8a8
--- /dev/null
+++ b/JNI/examples/bindingEncodeExample/res/layout/alert_diag.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/layout_root"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:orientation="vertical"
+    android:padding="10dp" >
+
+    <TextView
+        android:id="@+id/textView"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:inputType="numberDecimal"
+        android:text="Input the number: "
+        android:textAppearance="?android:attr/textAppearanceLarge" />
+
+    <EditText
+        android:id="@+id/userInput"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:inputType="numberDecimal" >
+
+        <requestFocus />
+    </EditText>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/JNI/examples/bindingEncodeExample/res/layout/audio_dialog_settings.xml b/JNI/examples/bindingEncodeExample/res/layout/audio_dialog_settings.xml
new file mode 100644
index 0000000..54a11c9
--- /dev/null
+++ b/JNI/examples/bindingEncodeExample/res/layout/audio_dialog_settings.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="#ffffff"
+    android:shrinkColumns="*"
+    android:stretchColumns="*" >
+
+    <TableRow
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:gravity="center_horizontal" >
+    </TableRow>
+
+    <TableRow android:gravity="center" >
+
+        <Button
+            android:id="@+id/audioBitrateBtn"
+            style="@style/btn_bottommenu"
+            android:text="target bitrate:" />
+
+        <TextView
+            android:id="@+id/audioBitrateResult"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:inputType="numberDecimal"
+            android:text="200"
+            android:textColor="@color/text_color" >
+        </TextView>
+    </TableRow>
+
+    <TableRow android:gravity="center" >
+
+        <Button
+            android:id="@+id/minAudioBitrateBtn"
+            style="@style/btn_bottommenu"
+            android:text="Minimum Bitrate:" />
+
+        <TextView
+            android:id="@+id/minAudioBitrateResult"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:text="100"
+            android:textColor="@color/text_color" />
+    </TableRow>
+
+    <TableRow android:gravity="center" >
+
+        <Button
+            android:id="@+id/maxAudioBitrateBtn"
+            style="@style/btn_bottommenu"
+            android:text="Maximum Bitrate:" />
+
+        <TextView
+            android:id="@+id/maxAudioBitrateResult"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:text="500"
+            android:textColor="@color/text_color" />
+    </TableRow>
+
+</TableLayout>
\ No newline at end of file
diff --git a/JNI/examples/bindingEncodeExample/res/layout/file_explore.xml b/JNI/examples/bindingEncodeExample/res/layout/file_explore.xml
new file mode 100644
index 0000000..4494103
--- /dev/null
+++ b/JNI/examples/bindingEncodeExample/res/layout/file_explore.xml
@@ -0,0 +1,23 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical" >
+
+    <TextView
+        android:id="@+id/path"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content" />
+
+    <ListView
+        android:id="@android:id/list"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content" />
+
+    <TextView
+        android:id="@android:id/empty"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:text="No Data" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/JNI/examples/bindingEncodeExample/res/layout/rows.xml b/JNI/examples/bindingEncodeExample/res/layout/rows.xml
new file mode 100644
index 0000000..3e603fb
--- /dev/null
+++ b/JNI/examples/bindingEncodeExample/res/layout/rows.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/rowtext"
+    android:layout_width="fill_parent"
+    android:layout_height="30sp"
+    android:textSize="25sp" />
\ No newline at end of file
diff --git a/JNI/examples/bindingEncodeExample/res/layout/video_dialog_settings.xml b/JNI/examples/bindingEncodeExample/res/layout/video_dialog_settings.xml
new file mode 100644
index 0000000..7e43921
--- /dev/null
+++ b/JNI/examples/bindingEncodeExample/res/layout/video_dialog_settings.xml
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="#ffffff"
+    android:shrinkColumns="*"
+    android:stretchColumns="*" >
+
+    <TableRow
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:gravity="center_horizontal" >
+    </TableRow>
+
+    <TableRow android:gravity="center" >
+
+        <Button
+            android:id="@+id/threadNumsBtn"
+            style="@style/btn_bottommenu"
+            android:text="thread numbers(default 1, range 1–num of cores):" />
+
+        <TextView
+            android:id="@+id/threadNumsResult"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:inputType="numberDecimal"
+            android:text="1"
+            android:textColor="@color/text_color" >
+        </TextView>
+    </TableRow>
+
+    <TableRow android:gravity="center" >
+
+        <Button
+            android:id="@+id/targetBitrateBtn"
+            style="@style/btn_bottommenu"
+            android:text="target bitrate (default 300kbps):" />
+
+        <TextView
+            android:id="@+id/targetBitrateResult"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:text="300"
+            android:textColor="@color/text_color" />
+    </TableRow>
+
+    <TableRow android:gravity="center" >
+
+        <Button
+            android:id="@+id/minQuantizerBtn"
+            style="@style/btn_bottommenu"
+            android:text="minimum quantizer (default 4, range 0–63):" />
+
+        <TextView
+            android:id="@+id/minQuantizerResult"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:text="4"
+            android:textColor="@color/text_color" />
+    </TableRow>
+
+    <TableRow android:gravity="center" >
+
+        <Button
+            android:id="@+id/maxQuantizerBtn"
+            style="@style/btn_bottommenu"
+            android:text="maximum quantizer (default 63, range qmin–63)" />
+
+        <TextView
+            android:id="@+id/maxQuantizerResult"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:text="63"
+            android:textColor="@color/text_color" />
+    </TableRow>
+
+    <TableRow android:gravity="center" >
+
+        <Button
+            android:id="@+id/kfMinDistBtn"
+            style="@style/btn_bottommenu"
+            android:text="Minimum keyframe interval (frames):" />
+
+        <TextView
+            android:id="@+id/kfMinDistResult"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:text="0"
+            android:textColor="@color/text_color" />
+    </TableRow>
+
+    <TableRow android:gravity="center" >
+
+        <Button
+            android:id="@+id/kfMaxDistBtn"
+            style="@style/btn_bottommenu"
+            android:text=" Maximum keyframe interval (frames):" />
+
+        <TextView
+            android:id="@+id/kfMaxDistResult"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:text="360"
+            android:textColor="@color/text_color" />
+    </TableRow>
+
+    <TableRow android:gravity="center" >
+
+        <Button
+            android:id="@+id/cpuUsedBtn"
+            style="@style/btn_bottommenu"
+            android:text="cpu used (default 0, range -16-16):" />
+
+        <TextView
+            android:id="@+id/cpuUsedResult"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:text="1"
+            android:textColor="@color/text_color" />
+    </TableRow>
+
+</TableLayout>
\ No newline at end of file
diff --git a/JNI/examples/bindingEncodeExample/res/menu/main.xml b/JNI/examples/bindingEncodeExample/res/menu/main.xml
new file mode 100644
index 0000000..d227c49
--- /dev/null
+++ b/JNI/examples/bindingEncodeExample/res/menu/main.xml
@@ -0,0 +1,9 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+
+    <item
+        android:id="@+id/action_settings"
+        android:orderInCategory="100"
+        android:showAsAction="never"
+        android:title="@string/action_settings"/>
+
+</menu>
\ No newline at end of file
diff --git a/JNI/examples/bindingEncodeExample/res/values-sw600dp/dimens.xml b/JNI/examples/bindingEncodeExample/res/values-sw600dp/dimens.xml
new file mode 100644
index 0000000..1ba777d
--- /dev/null
+++ b/JNI/examples/bindingEncodeExample/res/values-sw600dp/dimens.xml
@@ -0,0 +1,8 @@
+<resources>
+
+    <!--
+         Customize dimensions originally defined in res/values/dimens.xml (such as
+         screen margins) for sw600dp devices (e.g. 7" tablets) here.
+    -->
+
+</resources>
\ No newline at end of file
diff --git a/JNI/examples/bindingEncodeExample/res/values-sw720dp-land/dimens.xml b/JNI/examples/bindingEncodeExample/res/values-sw720dp-land/dimens.xml
new file mode 100644
index 0000000..eee741a
--- /dev/null
+++ b/JNI/examples/bindingEncodeExample/res/values-sw720dp-land/dimens.xml
@@ -0,0 +1,9 @@
+<resources>
+
+    <!--
+         Customize dimensions originally defined in res/values/dimens.xml (such as
+         screen margins) for sw720dp devices (e.g. 10" tablets) in landscape here.
+    -->
+    <dimen name="activity_horizontal_margin">128dp</dimen>
+
+</resources>
\ No newline at end of file
diff --git a/JNI/examples/bindingEncodeExample/res/values-v11/styles.xml b/JNI/examples/bindingEncodeExample/res/values-v11/styles.xml
new file mode 100644
index 0000000..29bd2f6
--- /dev/null
+++ b/JNI/examples/bindingEncodeExample/res/values-v11/styles.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <!--  styles for bottom menu buttons -->
+      <style name="btn_bottommenu">
+        <item name="android:layout_height">80dip</item>
+        <item name="android:layout_width">80dip</item>
+        <item name="android:textStyle">bold</item>
+      <item name="android:gravity">center_horizontal|center_vertical</item>
+      <item name="android:textSize">12dip</item>
+      </style>
+      <style name="filler_15dip">
+        <item name="android:layout_width">fill_parent</item>
+        <item name="android:layout_height">5dip</item>
+        <item name="android:visibility">invisible</item>
+      </style>
+</resources>
\ No newline at end of file
diff --git a/JNI/examples/bindingEncodeExample/res/values-v14/styles.xml b/JNI/examples/bindingEncodeExample/res/values-v14/styles.xml
new file mode 100644
index 0000000..8d15a74
--- /dev/null
+++ b/JNI/examples/bindingEncodeExample/res/values-v14/styles.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <!-- styles for bottom menu buttons -->
+    <style name="btn_bottommenu">
+        <item name="android:layout_height">40dip</item>
+        <item name="android:layout_width">200dip</item>
+        <item name="android:textStyle">bold</item>
+        <item name="android:gravity">center_horizontal|center_vertical</item>
+        <item name="android:textSize">12dip</item>
+    </style>
+
+    <style name="filler_15dip">
+        <item name="android:layout_width">fill_parent</item>
+        <item name="android:layout_height">5dip</item>
+        <item name="android:visibility">invisible</item>
+    </style>
+
+</resources>
\ No newline at end of file
diff --git a/JNI/examples/bindingEncodeExample/res/values/colors.xml b/JNI/examples/bindingEncodeExample/res/values/colors.xml
new file mode 100644
index 0000000..4935935
--- /dev/null
+++ b/JNI/examples/bindingEncodeExample/res/values/colors.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <color name="background_color">#ff888888</color>
+    <color name="text_color">#FF0000</color>
+</resources>
diff --git a/JNI/examples/bindingEncodeExample/res/values/dimens.xml b/JNI/examples/bindingEncodeExample/res/values/dimens.xml
new file mode 100644
index 0000000..a6dd140
--- /dev/null
+++ b/JNI/examples/bindingEncodeExample/res/values/dimens.xml
@@ -0,0 +1,7 @@
+<resources>
+
+    <!-- Default screen margins, per the Android Design guidelines. -->
+    <dimen name="activity_horizontal_margin">16dp</dimen>
+    <dimen name="activity_vertical_margin">16dp</dimen>
+
+</resources>
\ No newline at end of file
diff --git a/JNI/examples/bindingEncodeExample/res/values/strings.xml b/JNI/examples/bindingEncodeExample/res/values/strings.xml
new file mode 100644
index 0000000..dfd46ae
--- /dev/null
+++ b/JNI/examples/bindingEncodeExample/res/values/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <string name="app_name">bindingEncodeExample</string>
+    <string name="action_settings">Settings</string>
+    <string name="hello_world">Hello world!</string>
+
+</resources>
\ No newline at end of file
diff --git a/JNI/examples/bindingEncodeExample/res/values/styles.xml b/JNI/examples/bindingEncodeExample/res/values/styles.xml
new file mode 100644
index 0000000..4a10ca4
--- /dev/null
+++ b/JNI/examples/bindingEncodeExample/res/values/styles.xml
@@ -0,0 +1,20 @@
+<resources>
+
+    <!--
+        Base application theme, dependent on API level. This theme is replaced
+        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
+    -->
+    <style name="AppBaseTheme" parent="android:Theme.Light">
+        <!--
+            Theme customizations available in newer API levels can go in
+            res/values-vXX/styles.xml, while customizations related to
+            backward-compatibility can go here.
+        -->
+    </style>
+
+    <!-- Application theme. -->
+    <style name="AppTheme" parent="AppBaseTheme">
+        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
+    </style>
+
+</resources>
\ No newline at end of file
diff --git a/JNI/examples/bindingEncodeExample/src/com/example/bindingEncodeExample/AudioEncoderSetting.java b/JNI/examples/bindingEncodeExample/src/com/example/bindingEncodeExample/AudioEncoderSetting.java
new file mode 100644
index 0000000..e826ae2
--- /dev/null
+++ b/JNI/examples/bindingEncodeExample/src/com/example/bindingEncodeExample/AudioEncoderSetting.java
@@ -0,0 +1,14 @@
+// Author:hkuang@google.com (Hangyu Kuang)
+
+package com.example.bindingEncodeExample;
+
+public class AudioEncoderSetting {
+    // Default audio encoder settings.
+    public static String mAduioFilePath = null;
+    // Rate control values. Set the min and max values to -1 to
+    // encode at an average bitrate. Use the same value for minimum, average,
+    // and maximum to encode at a constant bitrate. Values are in kilobits.
+    public static int mAudioBitrate = 64000;
+    public static int mMinAudioBitRate = -1;
+    public static int mMaxAudioBitrate = -1;
+}
diff --git a/JNI/examples/bindingEncodeExample/src/com/example/bindingEncodeExample/AudioEncoderSettingDialog.java b/JNI/examples/bindingEncodeExample/src/com/example/bindingEncodeExample/AudioEncoderSettingDialog.java
new file mode 100644
index 0000000..a42fd5f
--- /dev/null
+++ b/JNI/examples/bindingEncodeExample/src/com/example/bindingEncodeExample/AudioEncoderSettingDialog.java
@@ -0,0 +1,152 @@
+// Author:hkuang@google.com (Hangyu Kuang)
+
+package com.example.bindingEncodeExample;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.TextView;
+
+public class AudioEncoderSettingDialog extends Activity {
+
+    // UI stuff.
+    private Button mAudioBitrateButton;
+    private Button mMinAudioBitrateButton;
+    private Button mMaxAudioBitrateButton;
+    private TextView mAudioBitrateInput;
+    private TextView mMinAudioBitrateInput;
+    private TextView mMaxAudioBitrateInput;
+
+    final Context context = this;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.audio_dialog_settings);
+
+        // Setup audio bitrate display and button handler.
+        mAudioBitrateInput = (TextView) findViewById(R.id.audioBitrateResult);
+        mAudioBitrateInput.setText(String.valueOf(AudioEncoderSetting.mAudioBitrate));
+        mAudioBitrateButton = (Button) findViewById(R.id.audioBitrateBtn);
+        mAudioBitrateButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                LayoutInflater inflater = LayoutInflater.from(context);
+                View promptsView = inflater.inflate(R.layout.alert_diag, null);
+                AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
+                alertDialogBuilder.setView(promptsView);
+
+                final EditText userInput = (EditText) promptsView.findViewById(R.id.userInput);
+
+                // set dialog message
+                alertDialogBuilder.setCancelable(false).setPositiveButton(
+                        "OK", new DialogInterface.OnClickListener() {
+                            @Override
+                            public void onClick(DialogInterface dialog, int id) {
+                                mAudioBitrateInput.setText(userInput.getText());
+                                AudioEncoderSetting.mAudioBitrate =
+                                        Integer.parseInt(mAudioBitrateInput.getText().toString());
+                            }
+                        }).setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
+                            @Override
+                            public void onClick(DialogInterface dialog, int id) {
+                                dialog.cancel();
+                            }
+                        });
+
+                // create alert dialog
+                AlertDialog alertDialog = alertDialogBuilder.create();
+
+                // show it
+                alertDialog.show();
+            }
+        });
+
+        // SetupSet up minAudioBitrate display and button handler.
+        mMinAudioBitrateInput = (TextView) findViewById(R.id.minAudioBitrateResult);
+        mMinAudioBitrateInput.setText(String.valueOf(AudioEncoderSetting.mMinAudioBitRate));
+        mMinAudioBitrateButton = (Button) findViewById(R.id.minAudioBitrateBtn);
+        mMinAudioBitrateButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                LayoutInflater inflater = LayoutInflater.from(context);
+                View promptsView = inflater.inflate(R.layout.alert_diag, null);
+                AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
+                alertDialogBuilder.setView(promptsView);
+
+                final EditText userInput = (EditText) promptsView.findViewById(R.id.userInput);
+
+                // set dialog message
+                alertDialogBuilder.setCancelable(false).setPositiveButton(
+                        "OK", new DialogInterface.OnClickListener() {
+                            @Override
+                            public void onClick(DialogInterface dialog, int id) {
+                                mMinAudioBitrateInput.setText(userInput.getText());
+                                AudioEncoderSetting.mMinAudioBitRate =
+                                        Integer.parseInt(
+                                                mMinAudioBitrateInput.getText().toString());
+                            }
+                        }).setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
+                            @Override
+                            public void onClick(DialogInterface dialog, int id) {
+                                dialog.cancel();
+                            }
+                        });
+
+                // create alert dialog
+                AlertDialog alertDialog = alertDialogBuilder.create();
+
+                // show it
+                alertDialog.show();
+            }
+        });
+
+        // Set up maxAudioBitrate display and button handler.
+        mMaxAudioBitrateInput = (TextView) findViewById(
+                R.id.maxAudioBitrateResult);
+        mMaxAudioBitrateInput.setText(
+                String.valueOf(AudioEncoderSetting.mMaxAudioBitrate));
+        mMaxAudioBitrateButton = (Button) findViewById(R.id.maxAudioBitrateBtn);
+        mMaxAudioBitrateButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                LayoutInflater inflater = LayoutInflater.from(context);
+                View promptsView = inflater.inflate(R.layout.alert_diag, null);
+                AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
+                alertDialogBuilder.setView(promptsView);
+
+                final EditText userInput = (EditText) promptsView.findViewById(R.id.userInput);
+
+                // set dialog message
+                alertDialogBuilder.setCancelable(false).setPositiveButton(
+                        "OK", new DialogInterface.OnClickListener() {
+                            @Override
+                            public void onClick(DialogInterface dialog, int id) {
+                                mMaxAudioBitrateInput.setText(userInput.getText());
+                                AudioEncoderSetting.mMaxAudioBitrate =
+                                        Integer.parseInt(
+                                                mMaxAudioBitrateInput.getText().toString());
+                            }
+                        }).setNegativeButton(
+                                "Cancel", new DialogInterface.OnClickListener() {
+                                    @Override
+                                    public void onClick(DialogInterface dialog, int id) {
+                                        dialog.cancel();
+                                    }
+                                });
+
+                // create alert dialog
+                AlertDialog alertDialog = alertDialogBuilder.create();
+
+                // show it
+                alertDialog.show();
+            }
+        });
+    }
+}
\ No newline at end of file
diff --git a/JNI/examples/bindingEncodeExample/src/com/example/bindingEncodeExample/FileExplorer.java b/JNI/examples/bindingEncodeExample/src/com/example/bindingEncodeExample/FileExplorer.java
new file mode 100644
index 0000000..dd89e8b
--- /dev/null
+++ b/JNI/examples/bindingEncodeExample/src/com/example/bindingEncodeExample/FileExplorer.java
@@ -0,0 +1,100 @@
+// Author:hkuang@google.com (Hangyu Kuang)
+
+package com.example.bindingEncodeExample;
+
+import android.app.AlertDialog;
+import android.app.ListActivity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Environment;
+import android.view.View;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+public class FileExplorer extends ListActivity {
+    private static final String TAG = "FileExplorer";
+    private List<String> mItem = null;
+    private List<String> mPath = null;
+    private String mRoot;
+    private TextView mCurPath;
+    private Boolean mChoosingVideoFile = false;
+    private Boolean mChoosingAudioFile = false;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.file_explore);
+
+        Bundle extras = getIntent().getExtras();
+        String value1 = extras.getString(Intent.EXTRA_TEXT);
+        if (value1.equals("choosingVideo")) {
+            mChoosingVideoFile = true;
+        } else {
+            mChoosingAudioFile = true;
+        }
+
+        mCurPath = (TextView) findViewById(R.id.path);
+        mRoot = Environment.getExternalStorageDirectory().getPath();
+        getDir(mRoot);
+    }
+
+    private void getDir(String dirPath) {
+        mCurPath.setText("Path: " + dirPath);
+        mItem = new ArrayList<String>();
+        mPath = new ArrayList<String>();
+        File dir = new File(dirPath);
+        File[] files = dir.listFiles();
+
+        if (!dirPath.equals(mRoot)) {
+            mItem.add(mRoot);
+            mPath.add(mRoot);
+            mItem.add("../");
+            mPath.add(dir.getParent());
+        }
+
+        for (int i = 0; i < files.length; i++) {
+            File file = files[i];
+
+            if (!file.isHidden() && file.canRead()) {
+                mPath.add(file.getPath());
+                if (file.isDirectory()) {
+                    mItem.add(file.getName() + "/");
+                } else {
+                    mItem.add(file.getName());
+                }
+            }
+        }
+
+        ArrayAdapter<String> fileList = new ArrayAdapter<String>(this, R.layout.rows, mItem);
+        setListAdapter(fileList);
+    }
+
+    @Override
+    protected void onListItemClick(ListView l, View v, int position, long id) {
+        File file = new File(mPath.get(position));
+
+        if (file.isDirectory()) {
+            if (file.canRead()) {
+                getDir(mPath.get(position));
+            } else {
+                new AlertDialog.Builder(this).setIcon(R.drawable.ic_launcher)
+                .setTitle("[" + file.getName() + "] folder can't be read!")
+                .setPositiveButton("OK", null).show();
+            }
+        } else {
+            String filePath = file.getAbsolutePath();
+            if (mChoosingVideoFile == true) {
+                VideoEncoderSetting.mVideoFilePath = filePath;
+                mChoosingVideoFile = false;
+            } else {
+                AudioEncoderSetting.mAduioFilePath = filePath;
+                mChoosingAudioFile = false;
+            }
+            finish();
+        }
+    }
+}
\ No newline at end of file
diff --git a/JNI/examples/bindingEncodeExample/src/com/example/bindingEncodeExample/MainActivity.java b/JNI/examples/bindingEncodeExample/src/com/example/bindingEncodeExample/MainActivity.java
new file mode 100644
index 0000000..019554b
--- /dev/null
+++ b/JNI/examples/bindingEncodeExample/src/com/example/bindingEncodeExample/MainActivity.java
@@ -0,0 +1,512 @@
+// Author:hkuang@google.com (Hangyu Kuang)
+
+package com.example.bindingEncodeExample;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.media.MediaPlayer;
+import android.media.MediaPlayer.OnCompletionListener;
+import android.media.MediaPlayer.OnVideoSizeChangedListener;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.Environment;
+import android.util.Log;
+import android.view.Menu;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.View;
+import android.widget.Button;
+import android.widget.TextView;
+import com.google.libvorbis.AudioFrame;
+import com.google.libvorbis.VorbisEncConfig;
+import com.google.libvorbis.VorbisEncoderC;
+import com.google.libvorbis.VorbisException;
+import com.google.libvpx.LibVpxEnc;
+import com.google.libvpx.LibVpxEncConfig;
+import com.google.libvpx.Rational;
+import com.google.libvpx.VpxCodecCxPkt;
+import com.google.libwebm.mkvmuxer.AudioTrack;
+import com.google.libwebm.mkvmuxer.MkvWriter;
+import com.google.libwebm.mkvmuxer.Segment;
+import com.google.libwebm.mkvmuxer.SegmentInfo;
+import com.google.utils.WavReader;
+import com.google.utils.Y4MReader;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+
+public class MainActivity extends Activity
+implements OnVideoSizeChangedListener, OnCompletionListener {
+    private static final String TAG = "bindingEncodeExample";
+
+    // Constants.
+    private static final int VIDEO_FILE_CHOOSE = 1;
+    private static final int AUDIO_FILE_CHOOSE = 2;
+    private static final int VIDEO_CONFIG = 3;
+    private static final int AUDIO_CONFIG = 4;
+
+    // UI stuff.
+    private int mVideoWidth = 0;
+    private int mVideoHeight = 0;
+    private SurfaceView mSurfaceView;
+    private SurfaceHolder mSurfaceHolder;
+    private Button mVideoConfigButton;
+    private Button mAudioConfigButton;
+    private Button mStartEncodeButton;
+    private Button mPlayVideoButton;
+    private Button mVideoSrcButton;
+    private Button mAudioSrcButton;
+    private TextView mVideoSrcDispView;
+    private TextView mAudioSrcDispView;
+    private TextView mOutputFilePathView;
+    private TextView mVideoConfigDispView;
+    private TextView mAudioConfigDispView;
+    private TextView mEncodingStatsDispView;
+    private TextView mPlayingStatsDispView;
+
+    // Mediaplayer for video playback.
+    private MediaPlayer mMediaPlayer;
+
+    // Output Webm file path.
+    private String mWebmFileOutputPath =
+            Environment.getExternalStorageDirectory().getAbsolutePath() + "/out.webm";
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+
+        // Setup all the view to display information.
+        mSurfaceView = (SurfaceView) findViewById(R.id.surface);
+        mVideoSrcDispView = (TextView) findViewById(R.id.videoSrcDisp);
+        mAudioSrcDispView = (TextView) findViewById(R.id.audioSrcDisp);
+        mEncodingStatsDispView = (TextView) findViewById(R.id.EncodingStatsDisp);
+        mPlayingStatsDispView = (TextView) findViewById(R.id.PlayingStatsDisp);
+        mVideoConfigDispView = (TextView) findViewById(R.id.videoEncodeConfigDisp);
+        mAudioConfigDispView = (TextView) findViewById(R.id.audioEncodeConfigDisp);
+        mOutputFilePathView = (TextView) findViewById(R.id.fileOutputDisp);
+
+        // Setup mediaplayer for video playback.
+        mMediaPlayer = new MediaPlayer();
+        mMediaPlayer.setOnVideoSizeChangedListener(this);
+        mMediaPlayer.setOnCompletionListener(this);
+
+        /**
+         * Initialize all the buttons.
+         */
+        // Setup video file select button.
+        mVideoSrcButton = (Button) findViewById(R.id.videoSrcBtn);
+        mVideoSrcButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                Intent intent = new Intent();
+                intent.setClass(getApplicationContext(),
+                        com.example.bindingEncodeExample.FileExplorer.class);
+                intent.putExtra(android.content.Intent.EXTRA_TEXT, "choosingVideo");
+                startActivityForResult(intent, VIDEO_FILE_CHOOSE);
+            }
+        });
+
+        // Setup audio file select button.
+        mAudioSrcButton = (Button) findViewById(R.id.audioSrcBtn);
+        mAudioSrcButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                Intent intent = new Intent();
+                intent.setClass(getApplicationContext(),
+                        com.example.bindingEncodeExample.FileExplorer.class);
+                intent.putExtra(android.content.Intent.EXTRA_TEXT, "choosingAudio");
+                startActivityForResult(intent, AUDIO_FILE_CHOOSE);
+            }
+        });
+
+        // Setup video config button.
+        mVideoConfigButton = (Button) findViewById(R.id.videoEncodeConfigBtn);
+        mVideoConfigButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                Intent settingIntent = new Intent();
+                settingIntent.setClass(getApplicationContext(),
+                        com.example.bindingEncodeExample.VideoEncoderSettingDialog.class);
+                startActivityForResult(settingIntent, VIDEO_CONFIG);
+            }
+        });
+
+        // Setup audio config button.
+        mAudioConfigButton = (Button) findViewById(R.id.audioEncodeConfigBtn);
+        mAudioConfigButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                Intent settingIntent = new Intent();
+                settingIntent.setClass(getApplicationContext(),
+                        com.example.bindingEncodeExample.AudioEncoderSettingDialog.class);
+                startActivityForResult(settingIntent, AUDIO_CONFIG);
+            }
+        });
+
+        // Setup start encode button.
+        mStartEncodeButton = (Button) findViewById(R.id.StartEncodeBtn);
+        mStartEncodeButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                // Start an aysnc encoder task in the background.
+                new EncodeY4mWavTask().execute((Void) null);
+            }
+        });
+
+        // Setup play video button.
+        mPlayVideoButton = (Button) findViewById(R.id.PlayVideoBtn);
+        mPlayVideoButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                mPlayingStatsDispView.setText("Playing Video");
+                try {
+                    mMediaPlayer.setDataSource(mWebmFileOutputPath);
+                    mSurfaceHolder = mSurfaceView.getHolder();
+                    mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
+                    mMediaPlayer.setDisplay(mSurfaceHolder);
+                    mMediaPlayer.prepare();
+                } catch (IllegalArgumentException e) {
+                    e.printStackTrace();
+                } catch (IllegalStateException e) {
+                    e.printStackTrace();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+                mMediaPlayer.start();
+            }
+        });
+
+        // Display the default video/audio configuration.
+        updateVideoConfigDisplay();
+        updateAudioConfigDisplay();
+
+        // Display the file output path.
+        mOutputFilePathView.setText(mWebmFileOutputPath);
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        // Inflate the menu; this adds items to the action bar if it is present.
+        getMenuInflater().inflate(R.menu.main, menu);
+        return true;
+    }
+
+    @Override
+    protected void onActivityResult(
+            int requestCode, int resultCode, Intent data) {
+        switch (requestCode) {
+        case VIDEO_FILE_CHOOSE:
+            // Update video source file path.
+            mVideoSrcDispView.setText(VideoEncoderSetting.mVideoFilePath);
+            break;
+
+        case AUDIO_FILE_CHOOSE:
+            // Update audio source file path.
+            mAudioSrcDispView.setText(AudioEncoderSetting.mAduioFilePath);
+            break;
+        case VIDEO_CONFIG:
+            // Update video encoder configuration.
+            updateVideoConfigDisplay();
+            break;
+        case AUDIO_CONFIG:
+            // Update audio encoder configuration.
+            updateAudioConfigDisplay();
+            break;
+        }
+        super.onActivityResult(requestCode, resultCode, data);
+    }
+
+    @Override
+    public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
+        Log.v(TAG, "onVideoSizeChanged called");
+        if (width == 0 || height == 0) {
+            Log.e(TAG, "invalid video width(" + width + ") or height(" + height + ")");
+            return;
+        }
+        // Update the video size and surface size.
+        mVideoWidth = width;
+        mVideoHeight = height;
+        mSurfaceHolder.setFixedSize(mVideoWidth, mVideoHeight);
+    }
+
+    @Override
+    public void onCompletion(MediaPlayer mp) {
+        mPlayingStatsDispView.setText("Done playing video");
+    }
+
+    // Display video configuration on the text view.
+    private void updateVideoConfigDisplay() {
+        String str;
+        str = "thread:" + VideoEncoderSetting.mThreadNum + " " + "bitrate:"
+                + VideoEncoderSetting.mTargetBitrate + " " + "minQuantizer:"
+                + VideoEncoderSetting.mMinQuantizer + " " + "maxQuantizer:"
+                + VideoEncoderSetting.mMaxQuantizer + " " + "kfMinDist:"
+                + VideoEncoderSetting.mKfMinDist + " " + "kfMaxDist:"
+                + VideoEncoderSetting.mKfMaxDist + " " + "cpu::"
+                + VideoEncoderSetting.mCpuUsed;
+        mVideoConfigDispView.setText(str);
+    }
+
+    // Display audio configuration on the text view.
+    private void updateAudioConfigDisplay() {
+        String str;
+        str = "AudioBitrate:" + AudioEncoderSetting.mAudioBitrate + " "
+                + "MinAudioBitrate:" + AudioEncoderSetting.mMinAudioBitRate + " "
+                + "MaxAudioBitrate:" + AudioEncoderSetting.mMaxAudioBitrate;
+        mAudioConfigDispView.setText(str);
+    }
+
+    // WebM encoder task running in the background.
+    private class EncodeY4mWavTask extends AsyncTask<Void, String, String> {
+        /*
+         * This function will encode an audio and video WebM file. The source
+         * video must be a Y4M file with raw i420 frames. The source audio must
+         * be a WAV file with raw PCM data. On success, it will return
+         * "Encoding Done". On failure, it will return error string.
+         */
+        @Override
+        protected String doInBackground(Void... params) {
+            StringBuilder error = new StringBuilder();
+            String y4mName = VideoEncoderSetting.mVideoFilePath;
+            String wavName = AudioEncoderSetting.mAduioFilePath;
+            int framesToEncode = 500; // maximum frames to encode.
+
+            LibVpxEncConfig vpxConfig = null;
+            LibVpxEnc vpxEncoder = null;
+            VorbisEncoderC vorbisEncoder = null;
+            VorbisEncConfig vorbisConfig = null;
+            MkvWriter mkvWriter = null;
+
+            try {
+                if (y4mName == null) {
+                    error.append("Please select video file using above button");
+                    return error.toString();
+                }
+
+                File y4mFile = new File(y4mName);
+                Y4MReader y4mReader;
+                try {
+                    y4mReader = new Y4MReader(y4mFile);
+                } catch (IOException e) {
+                    error.append("Invalid y4m file:" + y4mName);
+                    return error.toString();
+                }
+
+                vpxConfig = new LibVpxEncConfig(
+                        y4mReader.getWidth(), y4mReader.getHeight());
+                vpxEncoder = new LibVpxEnc(vpxConfig);
+
+                // libwebm expects nanosecond units
+                vpxConfig.setTimebase(1, 1000000000);
+
+                // setup video encoder configuration.
+                vpxConfig.setThreads(VideoEncoderSetting.mThreadNum);
+                vpxConfig.setRCTargetBitrate(VideoEncoderSetting.mTargetBitrate);
+                vpxConfig.setRCMinQuantizer(VideoEncoderSetting.mMinQuantizer);
+                vpxConfig.setRCMaxQuantizer(VideoEncoderSetting.mMaxQuantizer);
+                vpxConfig.setRCTargetBitrate(VideoEncoderSetting.mKfMinDist);
+                vpxConfig.setRCTargetBitrate(VideoEncoderSetting.mKfMaxDist);
+                vpxConfig.setRCTargetBitrate(VideoEncoderSetting.mCpuUsed);
+
+                Rational timeBase = vpxConfig.getTimebase();
+                Rational timeMultiplier = timeBase.multiply(y4mReader.getFrameRate()).reciprocal();
+                int framesIn = 1;
+
+                if (y4mName == null) {
+                    error.append("Please select audio file using above button");
+                    return error.toString();
+                }
+
+                File pcmFile = new File(wavName);
+                WavReader wavReader = null;
+                try {
+                    wavReader = new WavReader(pcmFile);
+                } catch (Exception e) {
+                    error.append("Invalid wav file:" + wavName);
+                    return error.toString();
+                }
+
+                final int channels = wavReader.nChannels();
+                final int sampleRate = wavReader.nSamplesPerSec();
+
+                try {
+                    vorbisConfig = new VorbisEncConfig(channels,
+                            sampleRate, wavReader.wBitsPerSample());
+                    vorbisConfig.setTimebase(1, 1000000000);
+                    vorbisConfig.setAverageBitrate(AudioEncoderSetting.mAudioBitrate);
+                    vorbisConfig.setMinimumBitrate(AudioEncoderSetting.mMinAudioBitRate);
+                    vorbisConfig.setMaximumBitrate(AudioEncoderSetting.mMaxAudioBitrate);
+                    vorbisEncoder = new VorbisEncoderC(vorbisConfig);
+                } catch (VorbisException e) {
+                    error.append("Error creating Vorbis encoder.");
+                    return error.toString();
+                }
+
+                mkvWriter = new MkvWriter();
+                if (!mkvWriter.open(mWebmFileOutputPath)) {
+                    error.append("WebM Output name is invalid or error while opening.");
+                    return error.toString();
+                }
+
+                Segment muxerSegment = new Segment();
+                if (!muxerSegment.init(mkvWriter)) {
+                    error.append("Could not initialize muxer segment.");
+                    return error.toString();
+                }
+
+                SegmentInfo muxerSegmentInfo = muxerSegment.getSegmentInfo();
+                muxerSegmentInfo.setWritingApp("y4mwavEncodeSample");
+
+                // Add video Track
+                long newVideoTrackNumber = muxerSegment.addVideoTrack(
+                        vpxConfig.getWidth(), vpxConfig.getHeight(), 0);
+                if (newVideoTrackNumber == 0) {
+                    error.append("Could not add video track.");
+                    return error.toString();
+                }
+
+                // Add audio Track
+                long newAudioTrackNumber = muxerSegment.addAudioTrack(sampleRate, channels, 0);
+                if (newAudioTrackNumber == 0) {
+                    error.append("Could not add audio track.");
+                    return error.toString();
+                }
+
+                AudioTrack muxerTrack =
+                        (AudioTrack) muxerSegment.getTrackByNumber(newAudioTrackNumber);
+                if (muxerTrack == null) {
+                    error.append("Could not get audio track.");
+                    return error.toString();
+                }
+
+                byte[] buffer = vorbisEncoder.CodecPrivate();
+                if (buffer == null) {
+                    error.append("Could not get audio private data.");
+                    return error.toString();
+                }
+                if (!muxerTrack.setCodecPrivate(buffer)) {
+                    error.append("Could not add audio private data.");
+                    return error.toString();
+                }
+
+                final int maxSamplesToRead = 1000;
+                AudioFrame vorbisFrame = null;
+                ArrayList<VpxCodecCxPkt> encPkt = null;
+                VpxCodecCxPkt pkt = null;
+                int pktIndex = 0;
+                boolean audioDone = false;
+                boolean videoDone = false;
+                boolean encoding = true;
+                while (encoding) {
+                    // Prime the audio encoder.
+                    while (vorbisFrame == null) {
+                        final int samplesLeft = wavReader.samplesRemaining();
+                        final int samplesToRead = Math.min(samplesLeft, maxSamplesToRead);
+                        if (samplesToRead > 0) {
+                            // Read raw audio data.
+                            byte[] pcmArray = null;
+                            try {
+                                pcmArray = wavReader.readSamples(samplesToRead);
+                            } catch (Exception e) {
+                                error.append("Could not read audio samples.");
+                                return error.toString();
+                            }
+
+                            if (!vorbisEncoder.Encode(pcmArray)) {
+                                error.append("Error encoding audio samples.");
+                                return error.toString();
+                            }
+
+                            vorbisFrame = vorbisEncoder.ReadCompressedFrame();
+                        } else {
+                            audioDone = true;
+                            break;
+                        }
+                    }
+
+                    if (encPkt == null) {
+                        // Read raw video data.
+                        byte[] rawVideoArray = y4mReader.getUncompressedFrame();
+                        if (rawVideoArray != null) {
+                            long frameStart = timeMultiplier.multiply(framesIn - 1).toLong();
+                            long nextFrameStart = timeMultiplier.multiply(framesIn++).toLong();
+
+                            encPkt = vpxEncoder.encodeFrame(rawVideoArray,
+                                    LibVpxEnc.VPX_IMG_FMT_I420, frameStart,
+                                    nextFrameStart - frameStart);
+
+                            // Get the first vpx encoded frame.
+                            pktIndex = 0;
+                            pkt = encPkt.get(pktIndex++);
+                        } else {
+                            videoDone = true;
+                        }
+                    }
+
+                    if (audioDone || videoDone || framesIn >= framesToEncode) break;
+
+                    if (!videoDone && (audioDone || pkt.pts <= vorbisFrame.pts)) {
+                        final boolean isKey = (pkt.flags & 0x1) == 1;
+                        String stats;
+                        stats = "Encoding " + (framesIn-1) + " frame";
+                        publishProgress(stats);
+                        if (!muxerSegment.addFrame(pkt.buffer, newVideoTrackNumber, pkt.pts,
+                                isKey)) {
+                            error.append("Could not add video frame.");
+                            return error.toString();
+                        }
+
+                        // Get the next vpx encoded frame.
+                        if (pktIndex < encPkt.size()) {
+                            pkt = encPkt.get(pktIndex++);
+                        } else {
+                            // Read the next raw video frame.
+                            encPkt = null;
+                        }
+                    } else if (!audioDone) {
+                        if (!muxerSegment.addFrame(vorbisFrame.buffer, newAudioTrackNumber,
+                                vorbisFrame.pts, true)) {
+                            error.append("Could not add audio frame.");
+                            return error.toString();
+                        }
+                        vorbisFrame = vorbisEncoder.ReadCompressedFrame();
+                    }
+                }
+
+                if (!muxerSegment.finalizeSegment()) {
+                    error.append("Finalization of segment failed.");
+                    return error.toString();
+                }
+
+            } catch (Exception e) {
+                error.append("Caught error in main encode loop.");
+                return error.toString();
+            } finally {
+                if (mkvWriter != null) {
+                    mkvWriter.close();
+                }
+            }
+
+            return "Encoding Done";
+        }
+
+        @Override
+        protected void onPreExecute() {
+            // Update the status on display.
+            mEncodingStatsDispView.setText("Start Encoding Video");
+        }
+
+        @Override
+        protected void onProgressUpdate(String... values) {
+            // Update the encoding status on display.
+            mEncodingStatsDispView.setText(values[0]);
+        }
+
+        @Override
+        protected void onPostExecute(String result) {
+            // Update the result on display.
+            mEncodingStatsDispView.setText(result);
+        }
+    }
+}
\ No newline at end of file
diff --git a/JNI/examples/bindingEncodeExample/src/com/example/bindingEncodeExample/VideoEncoderSetting.java b/JNI/examples/bindingEncodeExample/src/com/example/bindingEncodeExample/VideoEncoderSetting.java
new file mode 100644
index 0000000..40f2c21
--- /dev/null
+++ b/JNI/examples/bindingEncodeExample/src/com/example/bindingEncodeExample/VideoEncoderSetting.java
@@ -0,0 +1,15 @@
+// Author:hkuang@google.com (Hangyu Kuang)
+
+package com.example.bindingEncodeExample;
+
+public class VideoEncoderSetting {
+    // Default video encoder settings.
+    public static String mVideoFilePath = null;
+    public static int mThreadNum = 1;
+    public static int mTargetBitrate = 300;
+    public static int mMinQuantizer = 4;
+    public static int mMaxQuantizer = 63;
+    public static int mKfMinDist = 0;
+    public static int mKfMaxDist = 360;
+    public static int mCpuUsed = 1;
+}
\ No newline at end of file
diff --git a/JNI/examples/bindingEncodeExample/src/com/example/bindingEncodeExample/VideoEncoderSettingDialog.java b/JNI/examples/bindingEncodeExample/src/com/example/bindingEncodeExample/VideoEncoderSettingDialog.java
new file mode 100644
index 0000000..f5339d9
--- /dev/null
+++ b/JNI/examples/bindingEncodeExample/src/com/example/bindingEncodeExample/VideoEncoderSettingDialog.java
@@ -0,0 +1,314 @@
+// Author:hkuang@google.com (Hangyu Kuang)
+
+package com.example.bindingEncodeExample;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.TextView;
+
+public class VideoEncoderSettingDialog extends Activity {
+
+    // UI stuff.
+    private Button mThreadNumButton;
+    private Button mTargetBitrateButton;
+    private Button mMinQuantizerButton;
+    private Button mMaxQuantizerButton;
+    private Button mKfMinDistButton;
+    private Button mKfMaxDistButton;
+    private Button mCpuUsedButton;
+    private TextView mThreadNumInput;
+    private TextView mTargetBitrateInput;
+    private TextView mMinQuantizerInput;
+    private TextView mMaxQuantizerInput;
+    private TextView mKfMinDistInput;
+    private TextView mKfMaxDistInput;
+    private TextView mCpuUsedInput;
+
+    final Context mContext = this;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.video_dialog_settings);
+
+        // Setup thread number display and button handler.
+        mThreadNumInput = (TextView) findViewById(R.id.threadNumsResult);
+        mThreadNumInput.setText(String.valueOf(VideoEncoderSetting.mThreadNum));
+        mThreadNumButton = (Button) findViewById(R.id.threadNumsBtn);
+        mThreadNumButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                LayoutInflater inflater = LayoutInflater.from(mContext);
+                View view = inflater.inflate(R.layout.alert_diag, null);
+                AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
+                builder.setView(view);
+
+                final EditText userInput = (EditText) view.findViewById(R.id.userInput);
+
+                // set dialog message
+                builder.setCancelable(false).setPositiveButton(
+                        "OK", new DialogInterface.OnClickListener() {
+                            @Override
+                            public void onClick(DialogInterface dialog, int id) {
+                                mThreadNumInput.setText(userInput.getText());
+                                VideoEncoderSetting.mThreadNum =
+                                        Integer.parseInt(mThreadNumInput.getText().toString());
+                            }
+                        }).setNegativeButton(
+                                "Cancel", new DialogInterface.OnClickListener() {
+                                    @Override
+                                    public void onClick(DialogInterface dialog, int id) {
+                                        dialog.cancel();
+                                    }
+                                });
+
+                // create alert dialog
+                AlertDialog alertDialog = builder.create();
+
+                // show it
+                alertDialog.show();
+            }
+        });
+
+        // Setup target bitrate display and button handler.
+        mTargetBitrateInput = (TextView) findViewById(R.id.targetBitrateResult);
+        mTargetBitrateInput.setText(String.valueOf(VideoEncoderSetting.mTargetBitrate));
+        mTargetBitrateButton = (Button) findViewById(R.id.targetBitrateBtn);
+        mTargetBitrateButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                LayoutInflater inflater = LayoutInflater.from(mContext);
+                View view = inflater.inflate(R.layout.alert_diag, null);
+                AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
+                builder.setView(view);
+
+                final EditText userInput = (EditText) view.findViewById(R.id.userInput);
+
+                // set dialog message
+                builder.setCancelable(false).setPositiveButton(
+                        "OK", new DialogInterface.OnClickListener() {
+                            @Override
+                            public void onClick(DialogInterface dialog, int id) {
+                                mTargetBitrateInput.setText(userInput.getText());
+                                VideoEncoderSetting.mTargetBitrate =
+                                        Integer.parseInt(mTargetBitrateInput.getText().toString());
+                            }
+                        }).setNegativeButton(
+                                "Cancel", new DialogInterface.OnClickListener() {
+                                    @Override
+                                    public void onClick(DialogInterface dialog, int id) {
+                                        dialog.cancel();
+                                    }
+                                });
+
+                // create alert dialog
+                AlertDialog alertDialog = builder.create();
+
+                // show it
+                alertDialog.show();
+            }
+        });
+
+        // Setup minQuantizer display and button handler.
+        mMinQuantizerInput = (TextView) findViewById(R.id.minQuantizerResult);
+        mMinQuantizerInput.setText(String.valueOf(VideoEncoderSetting.mMinQuantizer));
+        mMinQuantizerButton = (Button) findViewById(R.id.minQuantizerBtn);
+        mMinQuantizerButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                LayoutInflater inflater = LayoutInflater.from(mContext);
+                View view = inflater.inflate(R.layout.alert_diag, null);
+                AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
+                builder.setView(view);
+
+                final EditText userInput = (EditText) view.findViewById(R.id.userInput);
+
+                // set dialog message
+                builder.setCancelable(false).setPositiveButton(
+                        "OK", new DialogInterface.OnClickListener() {
+                            @Override
+                            public void onClick(DialogInterface dialog, int id) {
+                                mMinQuantizerInput.setText(userInput.getText());
+                                VideoEncoderSetting.mMinQuantizer =
+                                        Integer.parseInt(mMinQuantizerInput.getText().toString());
+                            }
+                        }).setNegativeButton(
+                                "Cancel", new DialogInterface.OnClickListener() {
+                                    @Override
+                                    public void onClick(DialogInterface dialog, int id) {
+                                        dialog.cancel();
+                                    }
+                                });
+
+                // create alert dialog
+                AlertDialog alertDialog = builder.create();
+
+                // show it
+                alertDialog.show();
+            }
+        });
+
+        // Setup maxQuantizer display and button handler.
+        mMaxQuantizerInput = (TextView) findViewById(R.id.maxQuantizerResult);
+        mMaxQuantizerInput.setText(String.valueOf(VideoEncoderSetting.mMaxQuantizer));
+        mMaxQuantizerButton = (Button) findViewById(R.id.maxQuantizerBtn);
+        mMaxQuantizerButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                LayoutInflater inflater = LayoutInflater.from(mContext);
+                View view = inflater.inflate(R.layout.alert_diag, null);
+                AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
+                builder.setView(view);
+
+                final EditText userInput = (EditText) view.findViewById(R.id.userInput);
+
+                // set dialog message
+                builder.setCancelable(false).setPositiveButton(
+                        "OK", new DialogInterface.OnClickListener() {
+                            @Override
+                            public void onClick(DialogInterface dialog, int id) {
+                                mMaxQuantizerInput.setText(userInput.getText());
+                                VideoEncoderSetting.mMaxQuantizer =
+                                        Integer.parseInt(mMaxQuantizerInput.getText().toString());
+                            }
+                        }).setNegativeButton(
+                                "Cancel", new DialogInterface.OnClickListener() {
+                                    @Override
+                                    public void onClick(DialogInterface dialog, int id) {
+                                        dialog.cancel();
+                                    }
+                                });
+
+                // create alert dialog
+                AlertDialog alertDialog = builder.create();
+
+                // show it
+                alertDialog.show();
+            }
+        });
+
+        // Setup kfMinDist display and button handler.
+        mKfMinDistInput = (TextView) findViewById(R.id.kfMinDistResult);
+        mKfMinDistInput.setText(String.valueOf(VideoEncoderSetting.mKfMinDist));
+        mKfMinDistButton = (Button) findViewById(R.id.kfMinDistBtn);
+        mKfMinDistButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                LayoutInflater inflater = LayoutInflater.from(mContext);
+                View view = inflater.inflate(R.layout.alert_diag, null);
+                AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
+                builder.setView(view);
+
+                final EditText userInput = (EditText) view.findViewById(R.id.userInput);
+
+                // set dialog message
+                builder.setCancelable(false).setPositiveButton(
+                        "OK", new DialogInterface.OnClickListener() {
+                            @Override
+                            public void onClick(DialogInterface dialog, int id) {
+                                mKfMinDistInput.setText(userInput.getText());
+                                VideoEncoderSetting.mKfMinDist =
+                                        Integer.parseInt(mKfMinDistInput.getText().toString());
+                            }
+                        }).setNegativeButton(
+                                "Cancel", new DialogInterface.OnClickListener() {
+                                    @Override
+                                    public void onClick(DialogInterface dialog, int id) {
+                                        dialog.cancel();
+                                    }
+                                });
+
+                // create alert dialog
+                AlertDialog alertDialog = builder.create();
+
+                // show it
+                alertDialog.show();
+            }
+        });
+
+        // Setup kfMaxDist display and button handler.
+        mKfMaxDistInput = (TextView) findViewById(R.id.kfMaxDistResult);
+        mKfMaxDistInput.setText(String.valueOf(VideoEncoderSetting.mKfMaxDist));
+        mKfMaxDistButton = (Button) findViewById(R.id.kfMaxDistBtn);
+        mKfMaxDistButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                LayoutInflater inflater = LayoutInflater.from(mContext);
+                View view = inflater.inflate(R.layout.alert_diag, null);
+                AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
+                builder.setView(view);
+
+                final EditText userInput = (EditText) view.findViewById(R.id.userInput);
+
+                // set dialog message
+                builder.setCancelable(false).setPositiveButton(
+                        "OK", new DialogInterface.OnClickListener() {
+                            @Override
+                            public void onClick(DialogInterface dialog, int id) {
+                                mKfMaxDistInput.setText(userInput.getText());
+                                VideoEncoderSetting.mKfMaxDist =
+                                        Integer.parseInt(mKfMaxDistInput.getText().toString());
+                            }
+                        }).setNegativeButton(
+                                "Cancel", new DialogInterface.OnClickListener() {
+                                    @Override
+                                    public void onClick(DialogInterface dialog, int id) {
+                                        dialog.cancel();
+                                    }
+                                });
+
+                // create alert dialog
+                AlertDialog alertDialog = builder.create();
+
+                // show it
+                alertDialog.show();
+            }
+        });
+
+        // Setup cpuUsed display and button handler.
+        mCpuUsedInput = (TextView) findViewById(R.id.cpuUsedResult);
+        mCpuUsedInput.setText(String.valueOf(VideoEncoderSetting.mCpuUsed));
+        mCpuUsedButton = (Button) findViewById(R.id.cpuUsedBtn);
+        mCpuUsedButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                LayoutInflater inflater = LayoutInflater.from(mContext);
+                View view = inflater.inflate(R.layout.alert_diag, null);
+                AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
+                builder.setView(view);
+
+                final EditText userInput = (EditText) view.findViewById(R.id.userInput);
+
+                // set dialog message
+                builder.setCancelable(false).setPositiveButton(
+                        "OK", new DialogInterface.OnClickListener() {
+                            @Override
+                            public void onClick(DialogInterface dialog, int id) {
+                                mCpuUsedInput.setText(userInput.getText());
+                                VideoEncoderSetting.mCpuUsed = Integer.parseInt(
+                                        mCpuUsedInput.getText().toString());
+                            }
+                        }).setNegativeButton(
+                                "Cancel", new DialogInterface.OnClickListener() {
+                                    @Override
+                                    public void onClick(DialogInterface dialog, int id) {
+                                        dialog.cancel();
+                                    }
+                                });
+
+                // create alert dialog
+                AlertDialog alertDialog = builder.create();
+
+                // show it
+                alertDialog.show();
+            }
+        });
+    }
+}