Merge "minor clean-up GLclampx -> GLclampf" into kraken
diff --git a/docs/html/guide/developing/tools/emulator.jd b/docs/html/guide/developing/tools/emulator.jd
index 6363ab2..f07cdd5 100644
--- a/docs/html/guide/developing/tools/emulator.jd
+++ b/docs/html/guide/developing/tools/emulator.jd
@@ -1142,7 +1142,7 @@
emulator checks the value of the <code>http_proxy</code> environment variable at
startup and uses its value automatically, if defined. </p>
-<p>You can use the <code>-verbose-proxy</code> option to diagnose proxy
+<p>You can use the <code>-debug-proxy</code> option to diagnose proxy
connection problems.</p>
<a name="connecting"></a>
diff --git a/docs/html/guide/practices/design/performance.jd b/docs/html/guide/practices/design/performance.jd
index b3f8830..f22d2d3 100644
--- a/docs/html/guide/practices/design/performance.jd
+++ b/docs/html/guide/practices/design/performance.jd
@@ -279,7 +279,7 @@
<p>On devices without a JIT, it is true that invoking methods via a
variable with an exact type rather than an interface is slightly more
efficient. (So, for example, it was cheaper to invoke methods on a
-<code>Map map</code> than a <code>HashMap map</code>, even though in both
+<code>HashMap map</code> than a <code>Map map</code>, even though in both
cases the map was a <code>HashMap</code>.) It was not the case that this
was 2x slower; the actual difference was more like 6% slower. Furthermore,
the JIT makes the two effectively indistinguishable.</p>
diff --git a/docs/html/guide/publishing/app-signing.jd b/docs/html/guide/publishing/app-signing.jd
index 39b230b..8c37d7a 100644
--- a/docs/html/guide/publishing/app-signing.jd
+++ b/docs/html/guide/publishing/app-signing.jd
@@ -337,17 +337,6 @@
<td><code>-v</code></td><td>Enable verbose output.</td>
</tr>
<tr>
-<td><code>-keystore <keystore-name>.keystore</code></td><td>A name
-for the keystore containing the private key.</td>
-</tr>
-<tr>
-<td><code>-storepass <password></code></td><td><p>A password for the
-keystore.</p><p>As a security precaution, do not include this option
-in your command line unless you are working at a secure computer.
-If not supplied, Keytool prompts you to enter the password. In this
-way, your password is not stored in your shell history.</p></td>
-</tr>
-<tr>
<td><code>-alias <alias_name></code></td><td>An alias for the key. Only
the first 8 characters of the alias are used.</td>
</tr>
@@ -356,6 +345,11 @@
when generating the key. Both DSA and RSA are supported.</td>
</tr>
<tr>
+<td><code>-keysize <size></code></td><td>The size of each generated key
+(bits). If not supplied, Keytool uses a default key size of 1024 bits. In
+general, we recommend using a key size of 2048 bits or higher. </td>
+</tr>
+<tr>
<td><code>-dname <name></code></td><td><p>A Distinguished Name that describes
who created the key. The value is used as the issuer and subject fields in the
self-signed certificate. </p><p>Note that you do not need to specify this option
@@ -363,22 +357,31 @@
of the Distinguished Name fields (CN, OU, and so on).</p></td>
</tr>
<tr>
+<td><code>-keypass <password></code></td><td><p>The password for the
+key.</p> <p>As a security precaution, do not include this option in your command
+line. If not supplied, Keytool prompts you to enter the password. In this way,
+your password is not stored in your shell history.</p></td>
+</tr>
+<tr>
<td><code>-validity <valdays></code></td><td><p>The validity period for the
key, in days. </p><p><strong>Note:</strong> A value of 10000 or greater is recommended.</p></td>
</tr>
<tr>
-<td><code>-keypass <password></code></td><td><p>The password for the key.</p>
-<p>As a security precaution, do not include this option
-in your command line unless you are working at a secure computer.
-If not supplied, Keytool prompts you to enter the password. In this
-way, your password is not stored in your shell history.</p></td>
+<td><code>-keystore <keystore-name>.keystore</code></td><td>A name
+for the keystore containing the private key.</td>
+</tr>
+<tr>
+<td><code>-storepass <password></code></td><td><p>A password for the
+keystore.</p><p>As a security precaution, do not include this option in your
+command line. If not supplied, Keytool prompts you to enter the password. In
+this way, your password is not stored in your shell history.</p></td>
</tr>
</table>
<p>Here's an example of a Keytool command that generates a private key:</p>
<pre>$ keytool -genkey -v -keystore my-release-key.keystore
--alias alias_name -keyalg RSA -validity 10000</pre>
+-alias alias_name -keyalg RSA -keysize 2048 -validity 10000</pre>
<p>Running the example command above, Keytool prompts you to provide
passwords for the keystore and key, and to provide the Distinguished
diff --git a/docs/html/guide/topics/providers/content-providers.jd b/docs/html/guide/topics/providers/content-providers.jd
index 5da760a..30f8d8c 100644
--- a/docs/html/guide/topics/providers/content-providers.jd
+++ b/docs/html/guide/topics/providers/content-providers.jd
@@ -176,17 +176,7 @@
<p>
<p style="margin-left: 2em">{@code android.provider.Contacts.Phones.CONTENT_URI}
<br/>{@code android.provider.Contacts.Photos.CONTENT_URI}
-</p>
-
-<p>
-Similarly, the URIs for the table of recent phone calls and the table
-of calendar entries are:
-</p>
-
-<p>
-<p style="margin-left: 2em">{@code android.provider.CallLog.Calls.CONTENT_URI}
-<br/>{@code android.provider.Calendar.CONTENT_URI}
-</p>
+</p>
<p>
The URI constant is used in all interactions with the content provider.
diff --git a/docs/html/sdk/adt_download.jd b/docs/html/sdk/adt_download.jd
index 96896c7..f98caf5 100644
--- a/docs/html/sdk/adt_download.jd
+++ b/docs/html/sdk/adt_download.jd
@@ -22,11 +22,18 @@
<th>Notes</th>
</tr>
<tr>
- <td>0.9.6</td>
- <td><a href="http://dl-ssl.google.com/android/ADT-0.9.6.zip">ADT-0.9.6.zip</a></td>
+ <td>0.9.7</td>
+ <td><a href="http://dl-ssl.google.com/android/ADT-0.9.7.zip">ADT-0.9.7.zip</a></td>
<td><nobr>{@adtZipBytes} bytes</nobr></td>
<td>{@adtZipChecksum}</td>
- <td>Requires SDK Tools, Revision 5 <em><nobr>March 2009</nobr></em></td>
+ <td>Requires SDK Tools, Revision 6 <em><nobr>May 2010</nobr></em></td>
+ </tr>
+ <tr>
+ <td>0.9.6</td>
+ <td><a href="http://dl-ssl.google.com/android/ADT-0.9.6.zip">ADT-0.9.6.zip</a></td>
+ <td><nobr>7456339 bytes</nobr></td>
+ <td>ea45d271be52b87b5dd1c9fb17536223</td>
+ <td>Requires SDK Tools, Revision 5 <em><nobr>March 2010</nobr></em></td>
</tr>
<tr>
<td>0.9.5</td>
diff --git a/include/media/IEffect.h b/include/media/IEffect.h
new file mode 100644
index 0000000..6dad393
--- /dev/null
+++ b/include/media/IEffect.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#ifndef ANDROID_IEFFECT_H
+#define ANDROID_IEFFECT_H
+
+#include <utils/RefBase.h>
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
+#include <binder/IMemory.h>
+
+namespace android {
+
+class IEffect: public IInterface
+{
+public:
+ DECLARE_META_INTERFACE(Effect);
+
+ virtual status_t enable() = 0;
+
+ virtual status_t disable() = 0;
+
+ virtual status_t command(int cmdCode, int cmdSize, void *pCmdData, int *pReplySize, void *pReplyData) = 0;
+
+ virtual void disconnect() = 0;
+
+ virtual sp<IMemory> getCblk() const = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnEffect: public BnInterface<IEffect>
+{
+public:
+ virtual status_t onTransact( uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags = 0);
+};
+
+}; // namespace android
+
+#endif // ANDROID_IEFFECT_H
diff --git a/include/media/IEffectClient.h b/include/media/IEffectClient.h
new file mode 100644
index 0000000..d22daf8
--- /dev/null
+++ b/include/media/IEffectClient.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#ifndef ANDROID_IEFFECTCLIENT_H
+#define ANDROID_IEFFECTCLIENT_H
+
+#include <utils/RefBase.h>
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
+#include <binder/IMemory.h>
+
+namespace android {
+
+class IEffectClient: public IInterface
+{
+public:
+ DECLARE_META_INTERFACE(EffectClient);
+
+ virtual void controlStatusChanged(bool controlGranted) = 0;
+ virtual void enableStatusChanged(bool enabled) = 0;
+ virtual void commandExecuted(int cmdCode, int cmdSize, void *pCmdData, int replySize, void *pReplyData) = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnEffectClient: public BnInterface<IEffectClient>
+{
+public:
+ virtual status_t onTransact( uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags = 0);
+};
+
+}; // namespace android
+
+#endif // ANDROID_IEFFECTCLIENT_H
diff --git a/include/media/stagefright/CameraSource.h b/include/media/stagefright/CameraSource.h
index 42d6634..9d6b01d 100644
--- a/include/media/stagefright/CameraSource.h
+++ b/include/media/stagefright/CameraSource.h
@@ -19,6 +19,7 @@
#define CAMERA_SOURCE_H_
#include <media/stagefright/MediaBuffer.h>
+#include <media/stagefright/MediaBufferGroup.h>
#include <media/stagefright/MediaSource.h>
#include <utils/List.h>
#include <utils/RefBase.h>
@@ -61,6 +62,7 @@
int32_t mNumFramesReceived;
int32_t mNumFramesEncoded;
int32_t mNumFramesDropped;
+ MediaBufferGroup *mBufferGroup;
bool mStarted;
CameraSource(const sp<Camera> &camera);
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk
index 3adabcc..29cd2ee 100644
--- a/media/libmedia/Android.mk
+++ b/media/libmedia/Android.mk
@@ -26,7 +26,9 @@
MediaScannerClient.cpp \
autodetect.cpp \
IMediaDeathNotifier.cpp \
- MediaProfiles.cpp
+ MediaProfiles.cpp \
+ IEffect.cpp \
+ IEffectClient.cpp
LOCAL_SHARED_LIBRARIES := \
libui libcutils libutils libbinder libsonivox libicuuc libexpat libsurfaceflinger_client libcamera_client
diff --git a/media/libmedia/IEffect.cpp b/media/libmedia/IEffect.cpp
new file mode 100644
index 0000000..8e3ac71
--- /dev/null
+++ b/media/libmedia/IEffect.cpp
@@ -0,0 +1,191 @@
+/*
+**
+** Copyright 2010, 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.
+*/
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "IEffect"
+#include <utils/Log.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <binder/Parcel.h>
+#include <media/IEffect.h>
+
+namespace android {
+
+enum {
+ ENABLE = IBinder::FIRST_CALL_TRANSACTION,
+ DISABLE,
+ COMMAND,
+ DISCONNECT,
+ GET_CBLK
+};
+
+class BpEffect: public BpInterface<IEffect>
+{
+public:
+ BpEffect(const sp<IBinder>& impl)
+ : BpInterface<IEffect>(impl)
+ {
+ }
+
+ status_t enable()
+ {
+ LOGV("enable");
+ Parcel data, reply;
+ data.writeInterfaceToken(IEffect::getInterfaceDescriptor());
+ remote()->transact(ENABLE, data, &reply);
+ return reply.readInt32();
+ }
+
+ status_t disable()
+ {
+ LOGV("disable");
+ Parcel data, reply;
+ data.writeInterfaceToken(IEffect::getInterfaceDescriptor());
+ remote()->transact(DISABLE, data, &reply);
+ return reply.readInt32();
+ }
+
+ status_t command(int cmdCode, int cmdSize, void *pCmdData, int *pReplySize, void *pReplyData)
+ {
+ LOGV("command");
+ Parcel data, reply;
+ data.writeInterfaceToken(IEffect::getInterfaceDescriptor());
+ data.writeInt32(cmdCode);
+ int size = cmdSize;
+ if (pCmdData == NULL) {
+ size = 0;
+ }
+ data.writeInt32(size);
+ if (size) {
+ data.write(pCmdData, size);
+ }
+ if (pReplySize == NULL) {
+ size = 0;
+ } else {
+ size = *pReplySize;
+ }
+ data.writeInt32(size);
+ remote()->transact(COMMAND, data, &reply);
+ status_t status = reply.readInt32();
+ size = reply.readInt32();
+ if (size != 0 && pReplyData != NULL && pReplySize != NULL) {
+ reply.read(pReplyData, size);
+ *pReplySize = size;
+ }
+ return status;
+ }
+
+ void disconnect()
+ {
+ LOGV("disconnect");
+ Parcel data, reply;
+ data.writeInterfaceToken(IEffect::getInterfaceDescriptor());
+ remote()->transact(DISCONNECT, data, &reply);
+ return;
+ }
+
+ virtual sp<IMemory> getCblk() const
+ {
+ Parcel data, reply;
+ sp<IMemory> cblk;
+ data.writeInterfaceToken(IEffect::getInterfaceDescriptor());
+ status_t status = remote()->transact(GET_CBLK, data, &reply);
+ if (status == NO_ERROR) {
+ cblk = interface_cast<IMemory>(reply.readStrongBinder());
+ }
+ return cblk;
+ }
+ };
+
+IMPLEMENT_META_INTERFACE(Effect, "android.media.IEffect");
+
+// ----------------------------------------------------------------------
+
+status_t BnEffect::onTransact(
+ uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+ switch(code) {
+ case ENABLE: {
+ LOGV("ENABLE");
+ CHECK_INTERFACE(IEffect, data, reply);
+ reply->writeInt32(enable());
+ return NO_ERROR;
+ } break;
+
+ case DISABLE: {
+ LOGV("DISABLE");
+ CHECK_INTERFACE(IEffect, data, reply);
+ reply->writeInt32(disable());
+ return NO_ERROR;
+ } break;
+
+ case COMMAND: {
+ LOGV("COMMAND");
+ CHECK_INTERFACE(IEffect, data, reply);
+ int cmdCode = data.readInt32();
+ int cmdSize = data.readInt32();
+ char *cmd = NULL;
+ if (cmdSize) {
+ cmd = (char *)malloc(cmdSize);
+ data.read(cmd, cmdSize);
+ }
+ int replySize = data.readInt32();
+ int replySz = replySize;
+ char *resp = NULL;
+ if (replySize) {
+ resp = (char *)malloc(replySize);
+ }
+ status_t status = command(cmdCode, cmdSize, cmd, &replySz, resp);
+ reply->writeInt32(status);
+ if (replySz < replySize) {
+ replySize = replySz;
+ }
+ reply->writeInt32(replySize);
+ if (replySize) {
+ reply->write(resp, replySize);
+ }
+ if (cmd) {
+ free(cmd);
+ }
+ if (resp) {
+ free(resp);
+ }
+ return NO_ERROR;
+ } break;
+
+ case DISCONNECT: {
+ LOGV("DISCONNECT");
+ CHECK_INTERFACE(IEffect, data, reply);
+ disconnect();
+ return NO_ERROR;
+ } break;
+
+ case GET_CBLK: {
+ CHECK_INTERFACE(IEffect, data, reply);
+ reply->writeStrongBinder(getCblk()->asBinder());
+ return NO_ERROR;
+ } break;
+
+ default:
+ return BBinder::onTransact(code, data, reply, flags);
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
diff --git a/media/libmedia/IEffectClient.cpp b/media/libmedia/IEffectClient.cpp
new file mode 100644
index 0000000..e7659ae
--- /dev/null
+++ b/media/libmedia/IEffectClient.cpp
@@ -0,0 +1,141 @@
+/*
+**
+** Copyright 2010, 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.
+*/
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "IEffectClient"
+#include <utils/Log.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <media/IEffectClient.h>
+
+namespace android {
+
+enum {
+ CONTROL_STATUS_CHANGED = IBinder::FIRST_CALL_TRANSACTION,
+ ENABLE_STATUS_CHANGED,
+ COMMAND_EXECUTED
+};
+
+class BpEffectClient: public BpInterface<IEffectClient>
+{
+public:
+ BpEffectClient(const sp<IBinder>& impl)
+ : BpInterface<IEffectClient>(impl)
+ {
+ }
+
+ void controlStatusChanged(bool controlGranted)
+ {
+ LOGV("controlStatusChanged");
+ Parcel data, reply;
+ data.writeInterfaceToken(IEffectClient::getInterfaceDescriptor());
+ data.writeInt32((uint32_t)controlGranted);
+ remote()->transact(CONTROL_STATUS_CHANGED, data, &reply, IBinder::FLAG_ONEWAY);
+ }
+
+ void enableStatusChanged(bool enabled)
+ {
+ LOGV("enableStatusChanged");
+ Parcel data, reply;
+ data.writeInterfaceToken(IEffectClient::getInterfaceDescriptor());
+ data.writeInt32((uint32_t)enabled);
+ remote()->transact(ENABLE_STATUS_CHANGED, data, &reply, IBinder::FLAG_ONEWAY);
+ }
+
+ void commandExecuted(int cmdCode, int cmdSize, void *pCmdData, int replySize, void *pReplyData)
+ {
+ LOGV("commandExecuted");
+ Parcel data, reply;
+ data.writeInterfaceToken(IEffectClient::getInterfaceDescriptor());
+ data.writeInt32(cmdCode);
+ int size = cmdSize;
+ if (pCmdData == NULL) {
+ size = 0;
+ }
+ data.writeInt32(size);
+ if (size) {
+ data.write(pCmdData, size);
+ }
+ size = replySize;
+ if (pReplyData == NULL) {
+ size = 0;
+ }
+ data.writeInt32(size);
+ if (size) {
+ data.write(pReplyData, size);
+ }
+ remote()->transact(COMMAND_EXECUTED, data, &reply, IBinder::FLAG_ONEWAY);
+ }
+
+};
+
+IMPLEMENT_META_INTERFACE(EffectClient, "android.media.IEffectClient");
+
+// ----------------------------------------------------------------------
+
+status_t BnEffectClient::onTransact(
+ uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+ switch(code) {
+ case CONTROL_STATUS_CHANGED: {
+ LOGV("CONTROL_STATUS_CHANGED");
+ CHECK_INTERFACE(IEffectClient, data, reply);
+ bool hasControl = (bool)data.readInt32();
+ controlStatusChanged(hasControl);
+ return NO_ERROR;
+ } break;
+ case ENABLE_STATUS_CHANGED: {
+ LOGV("ENABLE_STATUS_CHANGED");
+ CHECK_INTERFACE(IEffectClient, data, reply);
+ bool enabled = (bool)data.readInt32();
+ enableStatusChanged(enabled);
+ return NO_ERROR;
+ } break;
+ case COMMAND_EXECUTED: {
+ LOGV("COMMAND_EXECUTED");
+ CHECK_INTERFACE(IEffectClient, data, reply);
+ int cmdCode = data.readInt32();
+ int cmdSize = data.readInt32();
+ char *cmd = NULL;
+ if (cmdSize) {
+ cmd = (char *)malloc(cmdSize);
+ data.read(cmd, cmdSize);
+ }
+ int replySize = data.readInt32();
+ char *resp = NULL;
+ if (replySize) {
+ resp = (char *)malloc(replySize);
+ data.read(resp, replySize);
+ }
+ commandExecuted(cmdCode, cmdSize, cmd, replySize, resp);
+ if (cmd) {
+ free(cmd);
+ }
+ if (resp) {
+ free(resp);
+ }
+ return NO_ERROR;
+ } break;
+ default:
+ return BBinder::onTransact(code, data, reply, flags);
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 681943f..8d15013 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -77,6 +77,8 @@
libstagefright_mp3dec \
libstagefright_vorbisdec \
libstagefright_matroska \
+ libstagefright_vpxdec \
+ libvpx \
LOCAL_SHARED_LIBRARIES += \
libstagefright_amrnb_common \
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index cd26e6b..87d7ebb 100644
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -104,6 +104,7 @@
mNumFramesReceived(0),
mNumFramesEncoded(0),
mNumFramesDropped(0),
+ mBufferGroup(NULL),
mStarted(false) {
String8 s = mCamera->getParameters();
printf("params: \"%s\"\n", s.string());
@@ -118,6 +119,23 @@
}
}
+static int bytesPerPixelTimes10(const char *colorFormat) {
+ LOGI("color format: %s", colorFormat);
+ return 20;
+#if 0
+ // XXX: Fix Camera Hal bug?
+ // On sholes, it returns CameraParameters::PIXEL_FORMAT_YUV420SP???
+ if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV422SP) ||
+ !strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV422I) ||
+ !strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_RGB565)) {
+ return 20;
+ } else if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV420SP)) {
+ return 15;
+ }
+ CHECK_EQ(0, "Unknown color format");
+#endif
+}
+
status_t CameraSource::start(MetaData *) {
LOGV("start");
CHECK(!mStarted);
@@ -126,6 +144,12 @@
CHECK_EQ(OK, mCamera->startRecording());
mStarted = true;
+ mBufferGroup = new MediaBufferGroup();
+ String8 s = mCamera->getParameters();
+ CameraParameters params(s);
+ const char *colorFormat = params.getPreviewFormat();
+ const int size = (mWidth * mHeight * bytesPerPixelTimes10(colorFormat))/10;
+ mBufferGroup->add_buffer(new MediaBuffer(size));
return OK;
}
@@ -139,6 +163,8 @@
mCamera->stopRecording();
releaseQueuedFrames();
+ delete mBufferGroup;
+ mBufferGroup = NULL;
LOGI("Frames received/encoded/dropped: %d/%d/%d, timestamp (us) last/first: %lld/%lld",
mNumFramesReceived, mNumFramesEncoded, mNumFramesDropped,
mLastFrameTimestampUs, mFirstFrameTimeUs);
@@ -197,7 +223,7 @@
++mNumFramesEncoded;
}
- *buffer = new MediaBuffer(frame->size());
+ mBufferGroup->acquire_buffer(buffer);
memcpy((*buffer)->data(), frame->pointer(), frame->size());
(*buffer)->set_range(0, frame->size());
mCamera->releaseRecordingFrame(frame);
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 928a6c8..66011ca9 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -28,6 +28,7 @@
#include "include/M4vH263Decoder.h"
#include "include/MP3Decoder.h"
#include "include/VorbisDecoder.h"
+#include "include/VPXDecoder.h"
#include "include/ESDS.h"
@@ -76,6 +77,7 @@
FACTORY_CREATE(AVCDecoder)
FACTORY_CREATE(M4vH263Decoder)
FACTORY_CREATE(VorbisDecoder)
+FACTORY_CREATE(VPXDecoder)
FACTORY_CREATE_ENCODER(AMRNBEncoder)
FACTORY_CREATE_ENCODER(AMRWBEncoder)
FACTORY_CREATE_ENCODER(AACEncoder)
@@ -118,6 +120,7 @@
FACTORY_REF(AVCDecoder)
FACTORY_REF(M4vH263Decoder)
FACTORY_REF(VorbisDecoder)
+ FACTORY_REF(VPXDecoder)
};
for (size_t i = 0;
i < sizeof(kFactoryInfo) / sizeof(kFactoryInfo[0]); ++i) {
@@ -158,6 +161,7 @@
{ MEDIA_MIMETYPE_VIDEO_AVC, "AVCDecoder" },
// { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.PV.avcdec" },
{ MEDIA_MIMETYPE_AUDIO_VORBIS, "VorbisDecoder" },
+ { MEDIA_MIMETYPE_VIDEO_VPX, "VPXDecoder" },
};
static const CodecInfo kEncoderInfo[] = {
diff --git a/media/libstagefright/OggExtractor.cpp b/media/libstagefright/OggExtractor.cpp
index bd16db9..6013b6f 100644
--- a/media/libstagefright/OggExtractor.cpp
+++ b/media/libstagefright/OggExtractor.cpp
@@ -76,7 +76,7 @@
status_t seekToOffset(off_t offset);
status_t readNextPacket(MediaBuffer **buffer);
- void init();
+ status_t init();
sp<MetaData> getFileMetaData() { return mFileMeta; }
@@ -107,7 +107,7 @@
ssize_t readPage(off_t offset, Page *page);
status_t findNextPage(off_t startOffset, off_t *pageOffset);
- void verifyHeader(
+ status_t verifyHeader(
MediaBuffer *buffer, uint8_t type);
void parseFileMetaData();
@@ -308,6 +308,7 @@
totalSize += page->mLace[i];
}
+#if 0
String8 tmp;
for (size_t i = 0; i < page->mNumSegments; ++i) {
char x[32];
@@ -316,7 +317,8 @@
tmp.append(x);
}
- // LOGV("%c %s", page->mFlags & 1 ? '+' : ' ', tmp.string());
+ LOGV("%c %s", page->mFlags & 1 ? '+' : ' ', tmp.string());
+#endif
return sizeof(header) + page->mNumSegments + totalSize;
}
@@ -432,43 +434,60 @@
}
}
-void MyVorbisExtractor::init() {
+status_t MyVorbisExtractor::init() {
mMeta = new MetaData;
mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_VORBIS);
MediaBuffer *packet;
- CHECK_EQ(readNextPacket(&packet), OK);
+ status_t err;
+ if ((err = readNextPacket(&packet)) != OK) {
+ return err;
+ }
LOGV("read packet of size %d\n", packet->range_length());
- verifyHeader(packet, 1);
+ err = verifyHeader(packet, 1);
packet->release();
packet = NULL;
+ if (err != OK) {
+ return err;
+ }
- CHECK_EQ(readNextPacket(&packet), OK);
+ if ((err = readNextPacket(&packet)) != OK) {
+ return err;
+ }
LOGV("read packet of size %d\n", packet->range_length());
- verifyHeader(packet, 3);
+ err = verifyHeader(packet, 3);
packet->release();
packet = NULL;
+ if (err != OK) {
+ return err;
+ }
- CHECK_EQ(readNextPacket(&packet), OK);
+ if ((err = readNextPacket(&packet)) != OK) {
+ return err;
+ }
LOGV("read packet of size %d\n", packet->range_length());
- verifyHeader(packet, 5);
+ err = verifyHeader(packet, 5);
packet->release();
packet = NULL;
+ if (err != OK) {
+ return err;
+ }
mFirstDataOffset = mOffset + mCurrentPageSize;
+
+ return OK;
}
-void MyVorbisExtractor::verifyHeader(
+status_t MyVorbisExtractor::verifyHeader(
MediaBuffer *buffer, uint8_t type) {
const uint8_t *data =
(const uint8_t *)buffer->data() + buffer->range_offset();
size_t size = buffer->range_length();
- CHECK(size >= 7);
-
- CHECK_EQ(data[0], type);
- CHECK(!memcmp(&data[1], "vorbis", 6));
+ if (size < 7 || data[0] != type || memcmp(&data[1], "vorbis", 6)) {
+ return ERROR_MALFORMED;
+ }
ogg_buffer buf;
buf.data = (uint8_t *)data;
@@ -515,7 +534,9 @@
case 3:
{
- CHECK_EQ(0, _vorbis_unpack_comment(&mVc, &bits));
+ if (0 != _vorbis_unpack_comment(&mVc, &bits)) {
+ return ERROR_MALFORMED;
+ }
parseFileMetaData();
break;
@@ -523,12 +544,16 @@
case 5:
{
- CHECK_EQ(0, _vorbis_unpack_books(&mVi, &bits));
+ if (0 != _vorbis_unpack_books(&mVi, &bits)) {
+ return ERROR_MALFORMED;
+ }
mMeta->setData(kKeyVorbisBooks, 0, data, size);
break;
}
}
+
+ return OK;
}
uint64_t MyVorbisExtractor::approxBitrate() {
@@ -732,10 +757,11 @@
mInitCheck(NO_INIT),
mImpl(NULL) {
mImpl = new MyVorbisExtractor(mDataSource);
- CHECK_EQ(mImpl->seekToOffset(0), OK);
- mImpl->init();
+ mInitCheck = mImpl->seekToOffset(0);
- mInitCheck = OK;
+ if (mInitCheck == OK) {
+ mInitCheck = mImpl->init();
+ }
}
OggExtractor::~OggExtractor() {
diff --git a/media/libstagefright/codecs/on2/Android.mk b/media/libstagefright/codecs/on2/Android.mk
new file mode 100644
index 0000000..2e431205
--- /dev/null
+++ b/media/libstagefright/codecs/on2/Android.mk
@@ -0,0 +1,4 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/media/libstagefright/codecs/on2/dec/Android.mk b/media/libstagefright/codecs/on2/dec/Android.mk
new file mode 100644
index 0000000..03dfb75
--- /dev/null
+++ b/media/libstagefright/codecs/on2/dec/Android.mk
@@ -0,0 +1,16 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ VPXDecoder.cpp
+
+LOCAL_MODULE := libstagefright_vpxdec
+
+LOCAL_C_INCLUDES := \
+ $(TOP)/frameworks/base/media/libstagefright/include \
+ $(TOP)/external/opencore/extern_libs_v2/khronos/openmax/include \
+ $(TOP)/external/libvpx \
+ $(TOP)/external/libvpx/vpx_codec \
+ $(TOP)/external/libvpx/vpx_ports
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/media/libstagefright/codecs/on2/dec/VPXDecoder.cpp b/media/libstagefright/codecs/on2/dec/VPXDecoder.cpp
new file mode 100644
index 0000000..bad8956
--- /dev/null
+++ b/media/libstagefright/codecs/on2/dec/VPXDecoder.cpp
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "VPXDecoder"
+#include <utils/Log.h>
+
+#include "VPXDecoder.h"
+
+#include <OMX_Component.h>
+
+#include <media/stagefright/MediaBufferGroup.h>
+#include <media/stagefright/MediaDebug.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/Utils.h>
+
+#include "vpx_codec/vpx_decoder.h"
+#include "vp8/vp8dx.h"
+
+namespace android {
+
+VPXDecoder::VPXDecoder(const sp<MediaSource> &source)
+ : mSource(source),
+ mStarted(false),
+ mBufferSize(0),
+ mCtx(NULL),
+ mBufferGroup(NULL) {
+ sp<MetaData> inputFormat = source->getFormat();
+ const char *mime;
+ CHECK(inputFormat->findCString(kKeyMIMEType, &mime));
+ CHECK(!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_VPX));
+
+ CHECK(inputFormat->findInt32(kKeyWidth, &mWidth));
+ CHECK(inputFormat->findInt32(kKeyHeight, &mHeight));
+
+ mBufferSize = (mWidth * mHeight * 3) / 2;
+
+ mFormat = new MetaData;
+ mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
+ mFormat->setInt32(kKeyWidth, mWidth);
+ mFormat->setInt32(kKeyHeight, mHeight);
+ mFormat->setInt32(kKeyColorFormat, OMX_COLOR_FormatYUV420Planar);
+ mFormat->setCString(kKeyDecoderComponent, "VPXDecoder");
+
+ int64_t durationUs;
+ if (inputFormat->findInt64(kKeyDuration, &durationUs)) {
+ mFormat->setInt64(kKeyDuration, durationUs);
+ }
+}
+
+VPXDecoder::~VPXDecoder() {
+ if (mStarted) {
+ stop();
+ }
+}
+
+status_t VPXDecoder::start(MetaData *) {
+ if (mStarted) {
+ return UNKNOWN_ERROR;
+ }
+
+ status_t err = mSource->start();
+
+ if (err != OK) {
+ return err;
+ }
+
+ mCtx = new vpx_codec_ctx_t;
+ if (vpx_codec_dec_init(
+ (vpx_codec_ctx_t *)mCtx, &vpx_codec_vp8_dx_algo, NULL, 0)) {
+ LOGE("on2 decoder failed to initialize.");
+
+ mSource->stop();
+
+ return UNKNOWN_ERROR;
+ }
+
+ mBufferGroup = new MediaBufferGroup;
+ mBufferGroup->add_buffer(new MediaBuffer(mBufferSize));
+ mBufferGroup->add_buffer(new MediaBuffer(mBufferSize));
+
+ mStarted = true;
+
+ return OK;
+}
+
+status_t VPXDecoder::stop() {
+ if (!mStarted) {
+ return UNKNOWN_ERROR;
+ }
+
+ delete mBufferGroup;
+ mBufferGroup = NULL;
+
+ vpx_codec_destroy((vpx_codec_ctx_t *)mCtx);
+ delete (vpx_codec_ctx_t *)mCtx;
+ mCtx = NULL;
+
+ mSource->stop();
+
+ mStarted = false;
+
+ return OK;
+}
+
+sp<MetaData> VPXDecoder::getFormat() {
+ return mFormat;
+}
+
+status_t VPXDecoder::read(
+ MediaBuffer **out, const ReadOptions *options) {
+ *out = NULL;
+
+ MediaBuffer *input;
+ status_t err = mSource->read(&input, options);
+
+ if (err != OK) {
+ return err;
+ }
+
+ LOGV("read %d bytes from source\n", input->range_length());
+
+ if (vpx_codec_decode(
+ (vpx_codec_ctx_t *)mCtx,
+ (uint8_t *)input->data() + input->range_offset(),
+ input->range_length(),
+ NULL,
+ 0)) {
+ LOGE("on2 decoder failed to decode frame.");
+ input->release();
+ input = NULL;
+
+ return UNKNOWN_ERROR;
+ }
+
+ LOGV("successfully decoded 1 or more frames.");
+
+ int64_t timeUs;
+ CHECK(input->meta_data()->findInt64(kKeyTime, &timeUs));
+
+ input->release();
+ input = NULL;
+
+ vpx_codec_iter_t iter = NULL;
+ vpx_image_t *img = vpx_codec_get_frame((vpx_codec_ctx_t *)mCtx, &iter);
+
+ if (img == NULL) {
+ LOGI("on2 decoder did not return a frame.");
+
+ *out = new MediaBuffer(0);
+ return OK;
+ }
+
+ CHECK_EQ(img->fmt, IMG_FMT_I420);
+
+ int32_t width = img->d_w;
+ int32_t height = img->d_h;
+
+ if (width != mWidth || height != mHeight) {
+ LOGI("Image dimensions changed, width = %d, height = %d",
+ width, height);
+
+ mWidth = width;
+ mHeight = height;
+ mFormat->setInt32(kKeyWidth, width);
+ mFormat->setInt32(kKeyHeight, height);
+
+ mBufferSize = (mWidth * mHeight * 3) / 2;
+ delete mBufferGroup;
+ mBufferGroup = new MediaBufferGroup;
+ mBufferGroup->add_buffer(new MediaBuffer(mBufferSize));
+ mBufferGroup->add_buffer(new MediaBuffer(mBufferSize));
+
+ return INFO_FORMAT_CHANGED;
+ }
+
+ MediaBuffer *output;
+ CHECK_EQ(mBufferGroup->acquire_buffer(&output), OK);
+
+ const uint8_t *srcLine = (const uint8_t *)img->planes[PLANE_Y];
+ uint8_t *dst = (uint8_t *)output->data();
+ for (size_t i = 0; i < img->d_h; ++i) {
+ memcpy(dst, srcLine, img->d_w);
+
+ srcLine += img->stride[PLANE_Y];
+ dst += img->d_w;
+ }
+
+ srcLine = (const uint8_t *)img->planes[PLANE_U];
+ for (size_t i = 0; i < img->d_h / 2; ++i) {
+ memcpy(dst, srcLine, img->d_w / 2);
+
+ srcLine += img->stride[PLANE_U];
+ dst += img->d_w / 2;
+ }
+
+ srcLine = (const uint8_t *)img->planes[PLANE_V];
+ for (size_t i = 0; i < img->d_h / 2; ++i) {
+ memcpy(dst, srcLine, img->d_w / 2);
+
+ srcLine += img->stride[PLANE_V];
+ dst += img->d_w / 2;
+ }
+
+ output->set_range(0, (width * height * 3) / 2);
+
+ output->meta_data()->setInt64(kKeyTime, timeUs);
+
+ *out = output;
+
+ return OK;
+}
+
+} // namespace android
+
diff --git a/media/libstagefright/include/VPXDecoder.h b/media/libstagefright/include/VPXDecoder.h
new file mode 100644
index 0000000..550c612
--- /dev/null
+++ b/media/libstagefright/include/VPXDecoder.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#ifndef VPX_DECODER_H_
+
+#define VPX_DECODER_H_
+
+#include <media/stagefright/MediaSource.h>
+#include <utils/Vector.h>
+
+namespace android {
+
+struct MediaBufferGroup;
+
+struct VPXDecoder : public MediaSource {
+ VPXDecoder(const sp<MediaSource> &source);
+
+ virtual status_t start(MetaData *params);
+ virtual status_t stop();
+
+ virtual sp<MetaData> getFormat();
+
+ virtual status_t read(
+ MediaBuffer **buffer, const ReadOptions *options);
+
+protected:
+ virtual ~VPXDecoder();
+
+private:
+ sp<MediaSource> mSource;
+ bool mStarted;
+ int32_t mWidth, mHeight;
+ size_t mBufferSize;
+
+ void *mCtx;
+ MediaBufferGroup *mBufferGroup;
+
+ sp<MetaData> mFormat;
+
+ VPXDecoder(const VPXDecoder &);
+ VPXDecoder &operator=(const VPXDecoder &);
+};
+
+} // namespace android
+
+#endif // VPX_DECODER_H_
+
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index 552bed4..cbbc7be 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -494,15 +494,23 @@
* argv8 - Max SCB
*/
String str = String.format("softap set " + wlanIface + " " + softapIface +
- " \"%s\" %s %s", wifiConfig.SSID,
+ " %s %s %s", convertQuotedString(wifiConfig.SSID),
wifiConfig.allowedKeyManagement.get(KeyMgmt.WPA_PSK) ?
"wpa2-psk" : "open",
- wifiConfig.preSharedKey);
+ convertQuotedString(wifiConfig.preSharedKey));
mConnector.doCommand(str);
}
mConnector.doCommand(String.format("softap startap"));
}
+ private String convertQuotedString(String s) {
+ if (s == null) {
+ return s;
+ }
+ /* Replace \ with \\, then " with \" and add quotes at end */
+ return '"' + s.replaceAll("\\\\","\\\\\\\\").replaceAll("\"","\\\\\"") + '"';
+ }
+
public void stopAccessPoint() throws IllegalStateException {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
@@ -521,10 +529,10 @@
mConnector.doCommand(String.format("softap set " + wlanIface + " " + softapIface));
} else {
String str = String.format("softap set " + wlanIface + " " + softapIface +
- " \"%s\" %s %s", wifiConfig.SSID,
+ " %s %s %s", convertQuotedString(wifiConfig.SSID),
wifiConfig.allowedKeyManagement.get(KeyMgmt.WPA_PSK) ?
"wpa2-psk" : "open",
- wifiConfig.preSharedKey);
+ convertQuotedString(wifiConfig.preSharedKey));
mConnector.doCommand(str);
}
}