summaryrefslogtreecommitdiffstats
path: root/samples/browseable/BasicRenderScript
diff options
context:
space:
mode:
authorAlexander Lucas <alexlucas@google.com>2014-02-06 15:38:51 -0800
committerAlexander Lucas <alexlucas@google.com>2014-02-07 13:17:23 -0800
commit0b3758ea4e53f9bfd0b112eaa4a7dd7b7f4040f5 (patch)
tree8a092424bc4793e2daa6b5f62d2b081050774fff /samples/browseable/BasicRenderScript
parent01d72b37a87ce8781cd35d5aaa834b508f964be7 (diff)
downloadandroid_development-0b3758ea4e53f9bfd0b112eaa4a7dd7b7f4040f5.tar.gz
android_development-0b3758ea4e53f9bfd0b112eaa4a7dd7b7f4040f5.tar.bz2
android_development-0b3758ea4e53f9bfd0b112eaa4a7dd7b7f4040f5.zip
Adding new samples to browseable section of DAC
Change-Id: I58e10e787f5df668331fc04e97a6c2efcd75f76f
Diffstat (limited to 'samples/browseable/BasicRenderScript')
-rw-r--r--samples/browseable/BasicRenderScript/AndroidManifest.xml45
-rw-r--r--samples/browseable/BasicRenderScript/_index.jd13
-rwxr-xr-xsamples/browseable/BasicRenderScript/res/drawable-hdpi/ic_launcher.pngbin0 -> 4440 bytes
-rw-r--r--samples/browseable/BasicRenderScript/res/drawable-hdpi/tile.9.pngbin0 -> 196 bytes
-rwxr-xr-xsamples/browseable/BasicRenderScript/res/drawable-mdpi/ic_launcher.pngbin0 -> 2742 bytes
-rw-r--r--samples/browseable/BasicRenderScript/res/drawable-nodpi/data.jpgbin0 -> 76367 bytes
-rwxr-xr-xsamples/browseable/BasicRenderScript/res/drawable-xhdpi/ic_launcher.pngbin0 -> 6245 bytes
-rwxr-xr-xsamples/browseable/BasicRenderScript/res/drawable-xxhdpi/ic_launcher.pngbin0 -> 11130 bytes
-rwxr-xr-xsamples/browseable/BasicRenderScript/res/layout/activity_main.xml36
-rw-r--r--samples/browseable/BasicRenderScript/res/layout/main_layout.xml22
-rw-r--r--samples/browseable/BasicRenderScript/res/values-sw600dp/template-dimens.xml24
-rw-r--r--samples/browseable/BasicRenderScript/res/values-sw600dp/template-styles.xml25
-rw-r--r--samples/browseable/BasicRenderScript/res/values-v11/styles.xml24
-rw-r--r--samples/browseable/BasicRenderScript/res/values-v14/styles.xml12
-rw-r--r--samples/browseable/BasicRenderScript/res/values/attrs.xml14
-rw-r--r--samples/browseable/BasicRenderScript/res/values/base-strings.xml32
-rw-r--r--samples/browseable/BasicRenderScript/res/values/colors.xml5
-rw-r--r--samples/browseable/BasicRenderScript/res/values/styles.xml22
-rw-r--r--samples/browseable/BasicRenderScript/res/values/template-dimens.xml32
-rw-r--r--samples/browseable/BasicRenderScript/res/values/template-styles.xml42
-rw-r--r--samples/browseable/BasicRenderScript/src/com.example.android.basicrenderscript/MainActivity.java190
-rw-r--r--samples/browseable/BasicRenderScript/src/com.example.android.common.media/CameraHelper.java182
-rw-r--r--samples/browseable/BasicRenderScript/src/com.example.android.common.media/MediaCodecWrapper.java386
23 files changed, 1106 insertions, 0 deletions
diff --git a/samples/browseable/BasicRenderScript/AndroidManifest.xml b/samples/browseable/BasicRenderScript/AndroidManifest.xml
new file mode 100644
index 000000000..e1e2dfc1b
--- /dev/null
+++ b/samples/browseable/BasicRenderScript/AndroidManifest.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+ Copyright 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.basicrenderscript"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk
+ android:minSdkVersion="8"
+ android:targetSdkVersion="19" />
+
+ <application
+ android:allowBackup="true"
+ android:label="@string/app_name"
+ android:icon="@drawable/ic_launcher"
+ android:theme="@style/AppTheme">
+
+ <activity
+ android:name=".MainActivity"
+ android:label="@string/app_name"
+ android:theme="@style/FullscreenTheme">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+
+</manifest>
diff --git a/samples/browseable/BasicRenderScript/_index.jd b/samples/browseable/BasicRenderScript/_index.jd
new file mode 100644
index 000000000..9c0f029b3
--- /dev/null
+++ b/samples/browseable/BasicRenderScript/_index.jd
@@ -0,0 +1,13 @@
+
+
+
+page.tags="BasicRenderScript"
+sample.group=RenderScript
+@jd:body
+
+<p>
+
+ BasicRenderScript sample demonstrates basic steps how to use renderScript.
+ In the sample, it performs graphical filter operation on a image with renderScript.
+
+ </p>
diff --git a/samples/browseable/BasicRenderScript/res/drawable-hdpi/ic_launcher.png b/samples/browseable/BasicRenderScript/res/drawable-hdpi/ic_launcher.png
new file mode 100755
index 000000000..75b3c9781
--- /dev/null
+++ b/samples/browseable/BasicRenderScript/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/BasicRenderScript/res/drawable-hdpi/tile.9.png b/samples/browseable/BasicRenderScript/res/drawable-hdpi/tile.9.png
new file mode 100644
index 000000000..135862883
--- /dev/null
+++ b/samples/browseable/BasicRenderScript/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/samples/browseable/BasicRenderScript/res/drawable-mdpi/ic_launcher.png b/samples/browseable/BasicRenderScript/res/drawable-mdpi/ic_launcher.png
new file mode 100755
index 000000000..4ccd98e09
--- /dev/null
+++ b/samples/browseable/BasicRenderScript/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/BasicRenderScript/res/drawable-nodpi/data.jpg b/samples/browseable/BasicRenderScript/res/drawable-nodpi/data.jpg
new file mode 100644
index 000000000..81a87b172
--- /dev/null
+++ b/samples/browseable/BasicRenderScript/res/drawable-nodpi/data.jpg
Binary files differ
diff --git a/samples/browseable/BasicRenderScript/res/drawable-xhdpi/ic_launcher.png b/samples/browseable/BasicRenderScript/res/drawable-xhdpi/ic_launcher.png
new file mode 100755
index 000000000..7c5aeed04
--- /dev/null
+++ b/samples/browseable/BasicRenderScript/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/BasicRenderScript/res/drawable-xxhdpi/ic_launcher.png b/samples/browseable/BasicRenderScript/res/drawable-xxhdpi/ic_launcher.png
new file mode 100755
index 000000000..3c45f511e
--- /dev/null
+++ b/samples/browseable/BasicRenderScript/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/BasicRenderScript/res/layout/activity_main.xml b/samples/browseable/BasicRenderScript/res/layout/activity_main.xml
new file mode 100755
index 000000000..be1aa49d9
--- /dev/null
+++ b/samples/browseable/BasicRenderScript/res/layout/activity_main.xml
@@ -0,0 +1,36 @@
+<!--
+ Copyright 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <LinearLayout style="@style/Widget.SampleMessageTile"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="@dimen/horizontal_page_margin"
+ android:layout_marginRight="@dimen/horizontal_page_margin"
+ android:layout_marginTop="@dimen/vertical_page_margin"
+ android:layout_marginBottom="@dimen/vertical_page_margin"
+ android:text="@string/intro_message" />
+ </LinearLayout>
+</LinearLayout>
diff --git a/samples/browseable/BasicRenderScript/res/layout/main_layout.xml b/samples/browseable/BasicRenderScript/res/layout/main_layout.xml
new file mode 100644
index 000000000..69695f07b
--- /dev/null
+++ b/samples/browseable/BasicRenderScript/res/layout/main_layout.xml
@@ -0,0 +1,22 @@
+<FrameLayout 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:background="#0099cc"
+ tools:context=".MainActivity">
+
+ <ImageView
+ android:id="@+id/imageView"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:scaleType="fitCenter"
+ android:src="@drawable/data" />
+
+ <SeekBar
+ android:id="@+id/seekBar1"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom"
+ android:layout_marginBottom="16dp" />
+
+</FrameLayout>
diff --git a/samples/browseable/BasicRenderScript/res/values-sw600dp/template-dimens.xml b/samples/browseable/BasicRenderScript/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 000000000..22074a2bd
--- /dev/null
+++ b/samples/browseable/BasicRenderScript/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/samples/browseable/BasicRenderScript/res/values-sw600dp/template-styles.xml b/samples/browseable/BasicRenderScript/res/values-sw600dp/template-styles.xml
new file mode 100644
index 000000000..03d197418
--- /dev/null
+++ b/samples/browseable/BasicRenderScript/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/samples/browseable/BasicRenderScript/res/values-v11/styles.xml b/samples/browseable/BasicRenderScript/res/values-v11/styles.xml
new file mode 100644
index 000000000..f3a90c687
--- /dev/null
+++ b/samples/browseable/BasicRenderScript/res/values-v11/styles.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <!--
+ Base application theme for API 11+. This theme completely replaces
+ AppBaseTheme from res/values/styles.xml on API 11+ devices.
+ -->
+ <style name="AppBaseTheme" parent="android:Theme.Holo.Light">
+ <!-- API 11 theme customizations can go here. -->
+ </style>
+
+ <style name="FullscreenTheme" parent="android:Theme.Holo">
+ <item name="android:actionBarStyle">@style/FullscreenActionBarStyle</item>
+ <item name="android:windowActionBarOverlay">true</item>
+ <item name="android:windowBackground">@null</item>
+ <item name="buttonBarStyle">?android:attr/buttonBarStyle</item>
+ <item name="buttonBarButtonStyle">?android:attr/buttonBarButtonStyle</item>
+ </style>
+
+ <style name="FullscreenActionBarStyle" parent="android:Widget.Holo.ActionBar">
+ <item name="android:background">@color/black_overlay</item>
+ </style>
+
+</resources>
diff --git a/samples/browseable/BasicRenderScript/res/values-v14/styles.xml b/samples/browseable/BasicRenderScript/res/values-v14/styles.xml
new file mode 100644
index 000000000..a91fd0372
--- /dev/null
+++ b/samples/browseable/BasicRenderScript/res/values-v14/styles.xml
@@ -0,0 +1,12 @@
+<resources>
+
+ <!--
+ Base application theme for API 14+. This theme completely replaces
+ AppBaseTheme from BOTH res/values/styles.xml and
+ res/values-v11/styles.xml on API 14+ devices.
+ -->
+ <style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar">
+ <!-- API 14 theme customizations can go here. -->
+ </style>
+
+</resources>
diff --git a/samples/browseable/BasicRenderScript/res/values/attrs.xml b/samples/browseable/BasicRenderScript/res/values/attrs.xml
new file mode 100644
index 000000000..e67df0a37
--- /dev/null
+++ b/samples/browseable/BasicRenderScript/res/values/attrs.xml
@@ -0,0 +1,14 @@
+<resources>
+
+ <!--
+ Declare custom theme attributes that allow changing which styles are
+ used for button bars depending on the API level.
+ ?android:attr/buttonBarStyle is new as of API 11 so this is
+ necessary to support previous API levels.
+ -->
+ <declare-styleable name="ButtonBarContainerTheme">
+ <attr name="buttonBarStyle" format="reference" />
+ <attr name="buttonBarButtonStyle" format="reference" />
+ </declare-styleable>
+
+</resources>
diff --git a/samples/browseable/BasicRenderScript/res/values/base-strings.xml b/samples/browseable/BasicRenderScript/res/values/base-strings.xml
new file mode 100644
index 000000000..a35b3206f
--- /dev/null
+++ b/samples/browseable/BasicRenderScript/res/values/base-strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+
+<resources>
+ <string name="app_name">BasicRenderScript</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+ BasicRenderScript sample demonstrates basic steps how to use renderScript.
+ In the sample, it performs graphical filter operation on a image with renderScript.
+
+
+ ]]>
+ </string>
+</resources>
diff --git a/samples/browseable/BasicRenderScript/res/values/colors.xml b/samples/browseable/BasicRenderScript/res/values/colors.xml
new file mode 100644
index 000000000..327c0604c
--- /dev/null
+++ b/samples/browseable/BasicRenderScript/res/values/colors.xml
@@ -0,0 +1,5 @@
+<resources>
+
+ <color name="black_overlay">#66000000</color>
+
+</resources>
diff --git a/samples/browseable/BasicRenderScript/res/values/styles.xml b/samples/browseable/BasicRenderScript/res/values/styles.xml
new file mode 100644
index 000000000..49299b98a
--- /dev/null
+++ b/samples/browseable/BasicRenderScript/res/values/styles.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+
+ <style name="FullscreenTheme" parent="android:Theme.NoTitleBar">
+ <item name="android:windowContentOverlay">@null</item>
+ <item name="android:windowBackground">@null</item>
+ <item name="buttonBarStyle">@style/ButtonBar</item>
+ <item name="buttonBarButtonStyle">@style/ButtonBarButton</item>
+ </style>
+
+ <style name="ButtonBar">
+ <item name="android:paddingLeft">2dp</item>
+ <item name="android:paddingTop">5dp</item>
+ <item name="android:paddingRight">2dp</item>
+ <item name="android:paddingBottom">0dp</item>
+ <item name="android:background">@android:drawable/bottom_bar</item>
+ </style>
+
+ <style name="ButtonBarButton" />
+
+</resources>
diff --git a/samples/browseable/BasicRenderScript/res/values/template-dimens.xml b/samples/browseable/BasicRenderScript/res/values/template-dimens.xml
new file mode 100644
index 000000000..39e710b5c
--- /dev/null
+++ b/samples/browseable/BasicRenderScript/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/samples/browseable/BasicRenderScript/res/values/template-styles.xml b/samples/browseable/BasicRenderScript/res/values/template-styles.xml
new file mode 100644
index 000000000..404623e3d
--- /dev/null
+++ b/samples/browseable/BasicRenderScript/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+ Copyright 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+ <style name="Theme.Sample" parent="Theme.Base" />
+
+ <style name="AppTheme" parent="Theme.Sample" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Widget.SampleMessageTile">
+ <item name="android:background">@drawable/tile</item>
+ <item name="android:shadowColor">#7F000000</item>
+ <item name="android:shadowDy">-3.5</item>
+ <item name="android:shadowRadius">2</item>
+ </style>
+
+</resources>
diff --git a/samples/browseable/BasicRenderScript/src/com.example.android.basicrenderscript/MainActivity.java b/samples/browseable/BasicRenderScript/src/com.example.android.basicrenderscript/MainActivity.java
new file mode 100644
index 000000000..ed6d5ad14
--- /dev/null
+++ b/samples/browseable/BasicRenderScript/src/com.example.android.basicrenderscript/MainActivity.java
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.basicrenderscript;
+
+import android.app.Activity;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.widget.ImageView;
+import android.widget.SeekBar;
+import android.widget.SeekBar.OnSeekBarChangeListener;
+import android.support.v8.renderscript.*;
+
+public class MainActivity extends Activity {
+ /* Number of bitmaps that is used for renderScript thread and UI thread synchronization.
+ Ideally, this can be reduced to 2, however in some devices, 2 buffers still showing tierings on UI.
+ Investigating a root cause.
+ */
+ private final int NUM_BITMAPS = 3;
+ private int mCurrentBitmap = 0;
+ private Bitmap mBitmapIn;
+ private Bitmap[] mBitmapsOut;
+ private ImageView mImageView;
+
+ private RenderScript mRS;
+ private Allocation mInAllocation;
+ private Allocation[] mOutAllocations;
+ private ScriptC_saturation mScript;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.main_layout);
+
+ /*
+ * Initialize UI
+ */
+ mBitmapIn = loadBitmap(R.drawable.data);
+ mBitmapsOut = new Bitmap[NUM_BITMAPS];
+ for (int i = 0; i < NUM_BITMAPS; ++i) {
+ mBitmapsOut[i] = Bitmap.createBitmap(mBitmapIn.getWidth(),
+ mBitmapIn.getHeight(), mBitmapIn.getConfig());
+ }
+
+ mImageView = (ImageView) findViewById(R.id.imageView);
+ mImageView.setImageBitmap(mBitmapsOut[mCurrentBitmap]);
+ mCurrentBitmap += (mCurrentBitmap + 1) % NUM_BITMAPS;
+
+ SeekBar seekbar = (SeekBar) findViewById(R.id.seekBar1);
+ seekbar.setProgress(50);
+ seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
+ public void onProgressChanged(SeekBar seekBar, int progress,
+ boolean fromUser) {
+ float max = 2.0f;
+ float min = 0.0f;
+ float f = (float) ((max - min) * (progress / 100.0) + min);
+ updateImage(f);
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {
+ }
+
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {
+ }
+ });
+
+ /*
+ * Create renderScript
+ */
+ createScript();
+
+ /*
+ * Invoke renderScript kernel and update imageView
+ */
+ updateImage(1.0f);
+ }
+
+ /*
+ * Initialize RenderScript
+ * In the sample, it creates RenderScript kernel that performs saturation manipulation.
+ */
+ private void createScript() {
+ //Initialize RS
+ mRS = RenderScript.create(this);
+
+ //Allocate buffers
+ mInAllocation = Allocation.createFromBitmap(mRS, mBitmapIn);
+ mOutAllocations = new Allocation[NUM_BITMAPS];
+ for (int i = 0; i < NUM_BITMAPS; ++i) {
+ mOutAllocations[i] = Allocation.createFromBitmap(mRS, mBitmapsOut[i]);
+ }
+
+ //Load script
+ mScript = new ScriptC_saturation(mRS);
+ }
+
+ /*
+ * In the AsyncTask, it invokes RenderScript intrinsics to do a filtering.
+ * After the filtering is done, an operation blocks at Allication.copyTo() in AsyncTask thread.
+ * Once all operation is finished at onPostExecute() in UI thread, it can invalidate and update ImageView UI.
+ */
+ private class RenderScriptTask extends AsyncTask<Float, Integer, Integer> {
+ Boolean issued = false;
+
+ protected Integer doInBackground(Float... values) {
+ int index = -1;
+ if (isCancelled() == false) {
+ issued = true;
+ index = mCurrentBitmap;
+
+ /*
+ * Set global variable in RS
+ */
+ mScript.set_saturationValue(values[0]);
+
+ /*
+ * Invoke saturation filter kernel
+ */
+ mScript.forEach_saturation(mInAllocation, mOutAllocations[index]);
+
+ /*
+ * Copy to bitmap and invalidate image view
+ */
+ mOutAllocations[index].copyTo(mBitmapsOut[index]);
+ mCurrentBitmap = (mCurrentBitmap + 1) % NUM_BITMAPS;
+ }
+ return index;
+ }
+
+ void updateView(Integer result) {
+ if (result != -1) {
+ // Request UI update
+ mImageView.setImageBitmap(mBitmapsOut[result]);
+ mImageView.invalidate();
+ }
+ }
+
+ protected void onPostExecute(Integer result) {
+ updateView(result);
+ }
+
+ protected void onCancelled(Integer result) {
+ if (issued) {
+ updateView(result);
+ }
+ }
+ }
+
+ RenderScriptTask currentTask = null;
+
+ /*
+ Invoke AsynchTask and cancel previous task.
+ When AsyncTasks are piled up (typically in slow device with heavy kernel),
+ Only the latest (and already started) task invokes RenderScript operation.
+ */
+ private void updateImage(final float f) {
+ if (currentTask != null)
+ currentTask.cancel(false);
+ currentTask = new RenderScriptTask();
+ currentTask.execute(f);
+ }
+
+ /*
+ Helper to load Bitmap from resource
+ */
+ private Bitmap loadBitmap(int resource) {
+ final BitmapFactory.Options options = new BitmapFactory.Options();
+ options.inPreferredConfig = Bitmap.Config.ARGB_8888;
+ return BitmapFactory.decodeResource(getResources(), resource, options);
+ }
+
+}
diff --git a/samples/browseable/BasicRenderScript/src/com.example.android.common.media/CameraHelper.java b/samples/browseable/BasicRenderScript/src/com.example.android.common.media/CameraHelper.java
new file mode 100644
index 000000000..1fa841675
--- /dev/null
+++ b/samples/browseable/BasicRenderScript/src/com.example.android.common.media/CameraHelper.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.common.media;
+
+import android.annotation.TargetApi;
+import android.hardware.Camera;
+import android.os.Build;
+import android.os.Environment;
+import android.util.Log;
+
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Camera related utilities.
+ */
+public class CameraHelper {
+
+ public static final int MEDIA_TYPE_IMAGE = 1;
+ public static final int MEDIA_TYPE_VIDEO = 2;
+
+ /**
+ * Iterate over supported camera preview sizes to see which one best fits the
+ * dimensions of the given view while maintaining the aspect ratio. If none can,
+ * be lenient with the aspect ratio.
+ *
+ * @param sizes Supported camera preview sizes.
+ * @param w The width of the view.
+ * @param h The height of the view.
+ * @return Best match camera preview size to fit in the view.
+ */
+ public static Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {
+ // Use a very small tolerance because we want an exact match.
+ final double ASPECT_TOLERANCE = 0.1;
+ double targetRatio = (double) w / h;
+ if (sizes == null)
+ return null;
+
+ Camera.Size optimalSize = null;
+
+ // Start with max value and refine as we iterate over available preview sizes. This is the
+ // minimum difference between view and camera height.
+ double minDiff = Double.MAX_VALUE;
+
+ // Target view height
+ int targetHeight = h;
+
+ // Try to find a preview size that matches aspect ratio and the target view size.
+ // Iterate over all available sizes and pick the largest size that can fit in the view and
+ // still maintain the aspect ratio.
+ for (Camera.Size size : sizes) {
+ double ratio = (double) size.width / size.height;
+ if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
+ continue;
+ if (Math.abs(size.height - targetHeight) < minDiff) {
+ optimalSize = size;
+ minDiff = Math.abs(size.height - targetHeight);
+ }
+ }
+
+ // Cannot find preview size that matches the aspect ratio, ignore the requirement
+ if (optimalSize == null) {
+ minDiff = Double.MAX_VALUE;
+ for (Camera.Size size : sizes) {
+ if (Math.abs(size.height - targetHeight) < minDiff) {
+ optimalSize = size;
+ minDiff = Math.abs(size.height - targetHeight);
+ }
+ }
+ }
+ return optimalSize;
+ }
+
+ /**
+ * @return the default camera on the device. Return null if there is no camera on the device.
+ */
+ public static Camera getDefaultCameraInstance() {
+ return Camera.open();
+ }
+
+
+ /**
+ * @return the default rear/back facing camera on the device. Returns null if camera is not
+ * available.
+ */
+ public static Camera getDefaultBackFacingCameraInstance() {
+ return getDefaultCamera(Camera.CameraInfo.CAMERA_FACING_BACK);
+ }
+
+ /**
+ * @return the default front facing camera on the device. Returns null if camera is not
+ * available.
+ */
+ public static Camera getDefaultFrontFacingCameraInstance() {
+ return getDefaultCamera(Camera.CameraInfo.CAMERA_FACING_FRONT);
+ }
+
+
+ /**
+ *
+ * @param position Physical position of the camera i.e Camera.CameraInfo.CAMERA_FACING_FRONT
+ * or Camera.CameraInfo.CAMERA_FACING_BACK.
+ * @return the default camera on the device. Returns null if camera is not available.
+ */
+ @TargetApi(Build.VERSION_CODES.GINGERBREAD)
+ private static Camera getDefaultCamera(int position) {
+ // Find the total number of cameras available
+ int mNumberOfCameras = Camera.getNumberOfCameras();
+
+ // Find the ID of the back-facing ("default") camera
+ Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
+ for (int i = 0; i < mNumberOfCameras; i++) {
+ Camera.getCameraInfo(i, cameraInfo);
+ if (cameraInfo.facing == position) {
+ return Camera.open(i);
+
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Creates a media file in the {@code Environment.DIRECTORY_PICTURES} directory. The directory
+ * is persistent and available to other applications like gallery.
+ *
+ * @param type Media type. Can be video or image.
+ * @return A file object pointing to the newly created file.
+ */
+ public static File getOutputMediaFile(int type){
+ // To be safe, you should check that the SDCard is mounted
+ // using Environment.getExternalStorageState() before doing this.
+ if (!Environment.getExternalStorageState().equalsIgnoreCase(Environment.MEDIA_MOUNTED)) {
+ return null;
+ }
+
+ File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
+ Environment.DIRECTORY_PICTURES), "CameraSample");
+ // This location works best if you want the created images to be shared
+ // between applications and persist after your app has been uninstalled.
+
+ // Create the storage directory if it does not exist
+ if (! mediaStorageDir.exists()){
+ if (! mediaStorageDir.mkdirs()) {
+ Log.d("CameraSample", "failed to create directory");
+ return null;
+ }
+ }
+
+ // Create a media file name
+ String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
+ File mediaFile;
+ if (type == MEDIA_TYPE_IMAGE){
+ mediaFile = new File(mediaStorageDir.getPath() + File.separator +
+ "IMG_"+ timeStamp + ".jpg");
+ } else if(type == MEDIA_TYPE_VIDEO) {
+ mediaFile = new File(mediaStorageDir.getPath() + File.separator +
+ "VID_"+ timeStamp + ".mp4");
+ } else {
+ return null;
+ }
+
+ return mediaFile;
+ }
+
+}
diff --git a/samples/browseable/BasicRenderScript/src/com.example.android.common.media/MediaCodecWrapper.java b/samples/browseable/BasicRenderScript/src/com.example.android.common.media/MediaCodecWrapper.java
new file mode 100644
index 000000000..a511221f5
--- /dev/null
+++ b/samples/browseable/BasicRenderScript/src/com.example.android.common.media/MediaCodecWrapper.java
@@ -0,0 +1,386 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.common.media;
+
+import android.media.*;
+import android.os.Handler;
+import android.os.Looper;
+import android.view.Surface;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayDeque;
+import java.util.Queue;
+
+/**
+ * Simplifies the MediaCodec interface by wrapping around the buffer processing operations.
+ */
+public class MediaCodecWrapper {
+
+ // Handler to use for {@code OutputSampleListener} and {code OutputFormatChangedListener}
+ // callbacks
+ private Handler mHandler;
+
+
+ // Callback when media output format changes.
+ public interface OutputFormatChangedListener {
+ void outputFormatChanged(MediaCodecWrapper sender, MediaFormat newFormat);
+ }
+
+ private OutputFormatChangedListener mOutputFormatChangedListener = null;
+
+ /**
+ * Callback for decodes frames. Observers can register a listener for optional stream
+ * of decoded data
+ */
+ public interface OutputSampleListener {
+ void outputSample(MediaCodecWrapper sender, MediaCodec.BufferInfo info, ByteBuffer buffer);
+ }
+
+ /**
+ * The {@link MediaCodec} that is managed by this class.
+ */
+ private MediaCodec mDecoder;
+
+ // References to the internal buffers managed by the codec. The codec
+ // refers to these buffers by index, never by reference so it's up to us
+ // to keep track of which buffer is which.
+ private ByteBuffer[] mInputBuffers;
+ private ByteBuffer[] mOutputBuffers;
+
+ // Indices of the input buffers that are currently available for writing. We'll
+ // consume these in the order they were dequeued from the codec.
+ private Queue<Integer> mAvailableInputBuffers;
+
+ // Indices of the output buffers that currently hold valid data, in the order
+ // they were produced by the codec.
+ private Queue<Integer> mAvailableOutputBuffers;
+
+ // Information about each output buffer, by index. Each entry in this array
+ // is valid if and only if its index is currently contained in mAvailableOutputBuffers.
+ private MediaCodec.BufferInfo[] mOutputBufferInfo;
+
+ // An (optional) stream that will receive decoded data.
+ private OutputSampleListener mOutputSampleListener;
+
+ private MediaCodecWrapper(MediaCodec codec) {
+ mDecoder = codec;
+ codec.start();
+ mInputBuffers = codec.getInputBuffers();
+ mOutputBuffers = codec.getOutputBuffers();
+ mOutputBufferInfo = new MediaCodec.BufferInfo[mOutputBuffers.length];
+ mAvailableInputBuffers = new ArrayDeque<Integer>(mOutputBuffers.length);
+ mAvailableOutputBuffers = new ArrayDeque<Integer>(mInputBuffers.length);
+ }
+
+ /**
+ * Releases resources and ends the encoding/decoding session.
+ */
+ public void stopAndRelease() {
+ mDecoder.stop();
+ mDecoder.release();
+ mDecoder = null;
+ mHandler = null;
+ }
+
+ /**
+ * Getter for the registered {@link OutputFormatChangedListener}
+ */
+ public OutputFormatChangedListener getOutputFormatChangedListener() {
+ return mOutputFormatChangedListener;
+ }
+
+ /**
+ *
+ * @param outputFormatChangedListener the listener for callback.
+ * @param handler message handler for posting the callback.
+ */
+ public void setOutputFormatChangedListener(final OutputFormatChangedListener
+ outputFormatChangedListener, Handler handler) {
+ mOutputFormatChangedListener = outputFormatChangedListener;
+
+ // Making sure we don't block ourselves due to a bad implementation of the callback by
+ // using a handler provided by client.
+ Looper looper;
+ mHandler = handler;
+ if (outputFormatChangedListener != null && mHandler == null) {
+ if ((looper = Looper.myLooper()) != null) {
+ mHandler = new Handler();
+ } else {
+ throw new IllegalArgumentException(
+ "Looper doesn't exist in the calling thread");
+ }
+ }
+ }
+
+ /**
+ * Constructs the {@link MediaCodecWrapper} wrapper object around the video codec.
+ * The codec is created using the encapsulated information in the
+ * {@link MediaFormat} object.
+ *
+ * @param trackFormat The format of the media object to be decoded.
+ * @param surface Surface to render the decoded frames.
+ * @return
+ */
+ public static MediaCodecWrapper fromVideoFormat(final MediaFormat trackFormat,
+ Surface surface) {
+ MediaCodecWrapper result = null;
+ MediaCodec videoCodec = null;
+
+ // BEGIN_INCLUDE(create_codec)
+ final String mimeType = trackFormat.getString(MediaFormat.KEY_MIME);
+
+ // Check to see if this is actually a video mime type. If it is, then create
+ // a codec that can decode this mime type.
+ if (mimeType.contains("video/")) {
+ videoCodec = MediaCodec.createDecoderByType(mimeType);
+ videoCodec.configure(trackFormat, surface, null, 0);
+
+ }
+
+ // If codec creation was successful, then create a wrapper object around the
+ // newly created codec.
+ if (videoCodec != null) {
+ result = new MediaCodecWrapper(videoCodec);
+ }
+ // END_INCLUDE(create_codec)
+
+ return result;
+ }
+
+
+ /**
+ * Write a media sample to the decoder.
+ *
+ * A "sample" here refers to a single atomic access unit in the media stream. The definition
+ * of "access unit" is dependent on the type of encoding used, but it typically refers to
+ * a single frame of video or a few seconds of audio. {@link android.media.MediaExtractor}
+ * extracts data from a stream one sample at a time.
+ *
+ * @param input A ByteBuffer containing the input data for one sample. The buffer must be set
+ * up for reading, with its position set to the beginning of the sample data and its limit
+ * set to the end of the sample data.
+ *
+ * @param presentationTimeUs The time, relative to the beginning of the media stream,
+ * at which this buffer should be rendered.
+ *
+ * @param flags Flags to pass to the decoder. See {@link MediaCodec#queueInputBuffer(int,
+ * int, int, long, int)}
+ *
+ * @throws MediaCodec.CryptoException
+ */
+ public boolean writeSample(final ByteBuffer input,
+ final MediaCodec.CryptoInfo crypto,
+ final long presentationTimeUs,
+ final int flags) throws MediaCodec.CryptoException, WriteException {
+ boolean result = false;
+ int size = input.remaining();
+
+ // check if we have dequed input buffers available from the codec
+ if (size > 0 && !mAvailableInputBuffers.isEmpty()) {
+ int index = mAvailableInputBuffers.remove();
+ ByteBuffer buffer = mInputBuffers[index];
+
+ // we can't write our sample to a lesser capacity input buffer.
+ if (size > buffer.capacity()) {
+ throw new MediaCodecWrapper.WriteException(String.format(
+ "Insufficient capacity in MediaCodec buffer: "
+ + "tried to write %d, buffer capacity is %d.",
+ input.remaining(),
+ buffer.capacity()));
+ }
+
+ buffer.clear();
+ buffer.put(input);
+
+ // Submit the buffer to the codec for decoding. The presentationTimeUs
+ // indicates the position (play time) for the current sample.
+ if (crypto == null) {
+ mDecoder.queueInputBuffer(index, 0, size, presentationTimeUs, flags);
+ } else {
+ mDecoder.queueSecureInputBuffer(index, 0, crypto, presentationTimeUs, flags);
+ }
+ result = true;
+ }
+ return result;
+ }
+
+ static MediaCodec.CryptoInfo cryptoInfo= new MediaCodec.CryptoInfo();
+
+ /**
+ * Write a media sample to the decoder.
+ *
+ * A "sample" here refers to a single atomic access unit in the media stream. The definition
+ * of "access unit" is dependent on the type of encoding used, but it typically refers to
+ * a single frame of video or a few seconds of audio. {@link android.media.MediaExtractor}
+ * extracts data from a stream one sample at a time.
+ *
+ * @param extractor Instance of {@link android.media.MediaExtractor} wrapping the media.
+ *
+ * @param presentationTimeUs The time, relative to the beginning of the media stream,
+ * at which this buffer should be rendered.
+ *
+ * @param flags Flags to pass to the decoder. See {@link MediaCodec#queueInputBuffer(int,
+ * int, int, long, int)}
+ *
+ * @throws MediaCodec.CryptoException
+ */
+ public boolean writeSample(final MediaExtractor extractor,
+ final boolean isSecure,
+ final long presentationTimeUs,
+ int flags) {
+ boolean result = false;
+ boolean isEos = false;
+
+ if (!mAvailableInputBuffers.isEmpty()) {
+ int index = mAvailableInputBuffers.remove();
+ ByteBuffer buffer = mInputBuffers[index];
+
+ // reads the sample from the file using extractor into the buffer
+ int size = extractor.readSampleData(buffer, 0);
+ if (size <= 0) {
+ flags |= MediaCodec.BUFFER_FLAG_END_OF_STREAM;
+ }
+
+ // Submit the buffer to the codec for decoding. The presentationTimeUs
+ // indicates the position (play time) for the current sample.
+ if (!isSecure) {
+ mDecoder.queueInputBuffer(index, 0, size, presentationTimeUs, flags);
+ } else {
+ extractor.getSampleCryptoInfo(cryptoInfo);
+ mDecoder.queueSecureInputBuffer(index, 0, cryptoInfo, presentationTimeUs, flags);
+ }
+
+ result = true;
+ }
+ return result;
+ }
+
+ /**
+ * Performs a peek() operation in the queue to extract media info for the buffer ready to be
+ * released i.e. the head element of the queue.
+ *
+ * @param out_bufferInfo An output var to hold the buffer info.
+ *
+ * @return True, if the peek was successful.
+ */
+ public boolean peekSample(MediaCodec.BufferInfo out_bufferInfo) {
+ // dequeue available buffers and synchronize our data structures with the codec.
+ update();
+ boolean result = false;
+ if (!mAvailableOutputBuffers.isEmpty()) {
+ int index = mAvailableOutputBuffers.peek();
+ MediaCodec.BufferInfo info = mOutputBufferInfo[index];
+ // metadata of the sample
+ out_bufferInfo.set(
+ info.offset,
+ info.size,
+ info.presentationTimeUs,
+ info.flags);
+ result = true;
+ }
+ return result;
+ }
+
+ /**
+ * Processes, releases and optionally renders the output buffer available at the head of the
+ * queue. All observers are notified with a callback. See {@link
+ * OutputSampleListener#outputSample(MediaCodecWrapper, android.media.MediaCodec.BufferInfo,
+ * java.nio.ByteBuffer)}
+ *
+ * @param render True, if the buffer is to be rendered on the {@link Surface} configured
+ *
+ */
+ public void popSample(boolean render) {
+ // dequeue available buffers and synchronize our data structures with the codec.
+ update();
+ if (!mAvailableOutputBuffers.isEmpty()) {
+ int index = mAvailableOutputBuffers.remove();
+
+ if (render && mOutputSampleListener != null) {
+ ByteBuffer buffer = mOutputBuffers[index];
+ MediaCodec.BufferInfo info = mOutputBufferInfo[index];
+ mOutputSampleListener.outputSample(this, info, buffer);
+ }
+
+ // releases the buffer back to the codec
+ mDecoder.releaseOutputBuffer(index, render);
+ }
+ }
+
+ /**
+ * Synchronize this object's state with the internal state of the wrapped
+ * MediaCodec.
+ */
+ private void update() {
+ // BEGIN_INCLUDE(update_codec_state)
+ int index;
+
+ // Get valid input buffers from the codec to fill later in the same order they were
+ // made available by the codec.
+ while ((index = mDecoder.dequeueInputBuffer(0)) != MediaCodec.INFO_TRY_AGAIN_LATER) {
+ mAvailableInputBuffers.add(index);
+ }
+
+
+ // Likewise with output buffers. If the output buffers have changed, start using the
+ // new set of output buffers. If the output format has changed, notify listeners.
+ MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
+ while ((index = mDecoder.dequeueOutputBuffer(info, 0)) != MediaCodec.INFO_TRY_AGAIN_LATER) {
+ switch (index) {
+ case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
+ mOutputBuffers = mDecoder.getOutputBuffers();
+ mOutputBufferInfo = new MediaCodec.BufferInfo[mOutputBuffers.length];
+ mAvailableOutputBuffers.clear();
+ break;
+ case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
+ if (mOutputFormatChangedListener != null) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mOutputFormatChangedListener
+ .outputFormatChanged(MediaCodecWrapper.this,
+ mDecoder.getOutputFormat());
+
+ }
+ });
+ }
+ break;
+ default:
+ // Making sure the index is valid before adding to output buffers. We've already
+ // handled INFO_TRY_AGAIN_LATER, INFO_OUTPUT_FORMAT_CHANGED &
+ // INFO_OUTPUT_BUFFERS_CHANGED i.e all the other possible return codes but
+ // asserting index value anyways for future-proofing the code.
+ if(index >= 0) {
+ mOutputBufferInfo[index] = info;
+ mAvailableOutputBuffers.add(index);
+ } else {
+ throw new IllegalStateException("Unknown status from dequeueOutputBuffer");
+ }
+ break;
+ }
+
+ }
+ // END_INCLUDE(update_codec_state)
+
+ }
+
+ private class WriteException extends Throwable {
+ private WriteException(final String detailMessage) {
+ super(detailMessage);
+ }
+ }
+}