summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
Diffstat (limited to 'media')
-rw-r--r--media/libeffects/downmix/Android.mk2
-rw-r--r--media/libeffects/downmix/EffectDownmix.c14
-rw-r--r--media/libeffects/loudness/Android.mk2
-rw-r--r--media/libeffects/loudness/EffectLoudnessEnhancer.cpp14
-rw-r--r--media/libeffects/lvm/wrapper/Android.mk4
-rw-r--r--media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp14
-rw-r--r--media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp14
-rw-r--r--media/libeffects/preprocessing/Android.mk2
-rw-r--r--media/libeffects/preprocessing/PreProcessing.cpp14
-rw-r--r--media/libeffects/proxy/Android.mk2
-rw-r--r--media/libeffects/proxy/EffectProxy.cpp14
-rw-r--r--media/libeffects/testlibs/Android.mk_4
-rw-r--r--media/libeffects/visualizer/Android.mk2
-rw-r--r--media/libeffects/visualizer/EffectVisualizer.cpp14
-rw-r--r--media/libmedia/AudioParameter.cpp5
-rw-r--r--media/libmedia/IDrm.cpp60
-rw-r--r--media/libmedia/MemoryLeakTrackUtil.cpp14
-rw-r--r--media/libmediaplayerservice/Drm.cpp46
-rw-r--r--media/libmediaplayerservice/Drm.h14
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.cpp27
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.h1
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp16
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h4
-rw-r--r--media/libnbaio/MonoPipe.cpp2
-rw-r--r--media/libstagefright/ACodec.cpp73
-rw-r--r--media/libstagefright/AwesomePlayer.cpp5
-rw-r--r--media/libstagefright/MPEG4Extractor.cpp204
-rw-r--r--media/libstagefright/MediaCodec.cpp6
-rw-r--r--media/libstagefright/MediaCodecList.cpp9
-rw-r--r--media/libstagefright/MediaDefs.cpp1
-rw-r--r--media/libstagefright/MetaData.cpp10
-rw-r--r--media/libstagefright/OMXCodec.cpp53
-rw-r--r--media/libstagefright/TimedEventQueue.cpp12
-rw-r--r--media/libstagefright/WVMExtractor.cpp2
-rw-r--r--media/libstagefright/codecs/avc/enc/SoftAVCEncoder.cpp6
-rw-r--r--media/libstagefright/httplive/M3UParser.cpp2
-rw-r--r--media/libstagefright/id3/ID3.cpp12
-rw-r--r--media/libstagefright/include/ID3.h4
-rw-r--r--media/libstagefright/include/MPEG4Extractor.h4
-rw-r--r--media/libstagefright/mpeg2ts/ATSParser.cpp6
-rw-r--r--media/libstagefright/mpeg2ts/ATSParser.h4
-rw-r--r--media/libstagefright/mpeg2ts/ESQueue.cpp190
-rw-r--r--media/libstagefright/mpeg2ts/ESQueue.h2
-rw-r--r--media/libstagefright/rtsp/ARTSPConnection.cpp1
-rw-r--r--media/libstagefright/rtsp/MyHandler.h38
-rw-r--r--media/mtp/MtpDataPacket.cpp2
-rw-r--r--media/mtp/MtpStringBuffer.cpp37
-rw-r--r--media/mtp/MtpStringBuffer.h5
48 files changed, 850 insertions, 143 deletions
diff --git a/media/libeffects/downmix/Android.mk b/media/libeffects/downmix/Android.mk
index 5d0a87c..2bb6dbe 100644
--- a/media/libeffects/downmix/Android.mk
+++ b/media/libeffects/downmix/Android.mk
@@ -13,7 +13,7 @@ LOCAL_MODULE:= libdownmix
LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/soundfx
+LOCAL_MODULE_RELATIVE_PATH := soundfx
ifeq ($(TARGET_OS)-$(TARGET_SIMULATOR),linux-true)
LOCAL_LDLIBS += -ldl
diff --git a/media/libeffects/downmix/EffectDownmix.c b/media/libeffects/downmix/EffectDownmix.c
index d571f17..d84bca6 100644
--- a/media/libeffects/downmix/EffectDownmix.c
+++ b/media/libeffects/downmix/EffectDownmix.c
@@ -61,13 +61,13 @@ const struct effect_interface_s gDownmixInterface = {
// This is the only symbol that needs to be exported
__attribute__ ((visibility ("default")))
audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
- tag : AUDIO_EFFECT_LIBRARY_TAG,
- version : EFFECT_LIBRARY_API_VERSION,
- name : "Downmix Library",
- implementor : "The Android Open Source Project",
- create_effect : DownmixLib_Create,
- release_effect : DownmixLib_Release,
- get_descriptor : DownmixLib_GetDescriptor,
+ .tag = AUDIO_EFFECT_LIBRARY_TAG,
+ .version = EFFECT_LIBRARY_API_VERSION,
+ .name = "Downmix Library",
+ .implementor = "The Android Open Source Project",
+ .create_effect = DownmixLib_Create,
+ .release_effect = DownmixLib_Release,
+ .get_descriptor = DownmixLib_GetDescriptor,
};
diff --git a/media/libeffects/loudness/Android.mk b/media/libeffects/loudness/Android.mk
index dcb7b27..edf964e 100644
--- a/media/libeffects/loudness/Android.mk
+++ b/media/libeffects/loudness/Android.mk
@@ -14,7 +14,7 @@ LOCAL_SHARED_LIBRARIES := \
liblog \
libstlport
-LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/soundfx
+LOCAL_MODULE_RELATIVE_PATH := soundfx
LOCAL_MODULE:= libldnhncr
LOCAL_C_INCLUDES := \
diff --git a/media/libeffects/loudness/EffectLoudnessEnhancer.cpp b/media/libeffects/loudness/EffectLoudnessEnhancer.cpp
index 5510caf..a5a1a3f 100644
--- a/media/libeffects/loudness/EffectLoudnessEnhancer.cpp
+++ b/media/libeffects/loudness/EffectLoudnessEnhancer.cpp
@@ -453,13 +453,13 @@ const struct effect_interface_s gLEInterface = {
// This is the only symbol that needs to be exported
__attribute__ ((visibility ("default")))
audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
- tag : AUDIO_EFFECT_LIBRARY_TAG,
- version : EFFECT_LIBRARY_API_VERSION,
- name : "Loudness Enhancer Library",
- implementor : "The Android Open Source Project",
- create_effect : LELib_Create,
- release_effect : LELib_Release,
- get_descriptor : LELib_GetDescriptor,
+ .tag = AUDIO_EFFECT_LIBRARY_TAG,
+ .version = EFFECT_LIBRARY_API_VERSION,
+ .name = "Loudness Enhancer Library",
+ .implementor = "The Android Open Source Project",
+ .create_effect = LELib_Create,
+ .release_effect = LELib_Release,
+ .get_descriptor = LELib_GetDescriptor,
};
}; // extern "C"
diff --git a/media/libeffects/lvm/wrapper/Android.mk b/media/libeffects/lvm/wrapper/Android.mk
index f1af389..68ba34c 100644
--- a/media/libeffects/lvm/wrapper/Android.mk
+++ b/media/libeffects/lvm/wrapper/Android.mk
@@ -13,7 +13,7 @@ LOCAL_CFLAGS += -fvisibility=hidden
LOCAL_MODULE:= libbundlewrapper
-LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/soundfx
+LOCAL_MODULE_RELATIVE_PATH := soundfx
LOCAL_STATIC_LIBRARIES += libmusicbundle
@@ -42,7 +42,7 @@ LOCAL_CFLAGS += -fvisibility=hidden
LOCAL_MODULE:= libreverbwrapper
-LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/soundfx
+LOCAL_MODULE_RELATIVE_PATH := soundfx
LOCAL_STATIC_LIBRARIES += libreverb
diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
index 9fcfba3..b6aea6c 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
@@ -3214,13 +3214,13 @@ const struct effect_interface_s gLvmEffectInterface = {
// This is the only symbol that needs to be exported
__attribute__ ((visibility ("default")))
audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
- tag : AUDIO_EFFECT_LIBRARY_TAG,
- version : EFFECT_LIBRARY_API_VERSION,
- name : "Effect Bundle Library",
- implementor : "NXP Software Ltd.",
- create_effect : android::EffectCreate,
- release_effect : android::EffectRelease,
- get_descriptor : android::EffectGetDescriptor,
+ .tag = AUDIO_EFFECT_LIBRARY_TAG,
+ .version = EFFECT_LIBRARY_API_VERSION,
+ .name = "Effect Bundle Library",
+ .implementor = "NXP Software Ltd.",
+ .create_effect = android::EffectCreate,
+ .release_effect = android::EffectRelease,
+ .get_descriptor = android::EffectGetDescriptor,
};
}
diff --git a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
index 2e22532..c98d62b 100644
--- a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
+++ b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
@@ -2147,13 +2147,13 @@ const struct effect_interface_s gReverbInterface = {
// This is the only symbol that needs to be exported
__attribute__ ((visibility ("default")))
audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
- tag : AUDIO_EFFECT_LIBRARY_TAG,
- version : EFFECT_LIBRARY_API_VERSION,
- name : "Reverb Library",
- implementor : "NXP Software Ltd.",
- create_effect : android::EffectCreate,
- release_effect : android::EffectRelease,
- get_descriptor : android::EffectGetDescriptor,
+ .tag = AUDIO_EFFECT_LIBRARY_TAG,
+ .version = EFFECT_LIBRARY_API_VERSION,
+ .name = "Reverb Library",
+ .implementor = "NXP Software Ltd.",
+ .create_effect = android::EffectCreate,
+ .release_effect = android::EffectRelease,
+ .get_descriptor = android::EffectGetDescriptor,
};
}
diff --git a/media/libeffects/preprocessing/Android.mk b/media/libeffects/preprocessing/Android.mk
index c344352..9e8cb83 100644
--- a/media/libeffects/preprocessing/Android.mk
+++ b/media/libeffects/preprocessing/Android.mk
@@ -5,7 +5,7 @@ include $(CLEAR_VARS)
LOCAL_MODULE:= libaudiopreprocessing
LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/soundfx
+LOCAL_MODULE_RELATIVE_PATH := soundfx
LOCAL_SRC_FILES:= \
PreProcessing.cpp
diff --git a/media/libeffects/preprocessing/PreProcessing.cpp b/media/libeffects/preprocessing/PreProcessing.cpp
index 1eb5d40..be4fa7e 100644
--- a/media/libeffects/preprocessing/PreProcessing.cpp
+++ b/media/libeffects/preprocessing/PreProcessing.cpp
@@ -1895,13 +1895,13 @@ int PreProcessingLib_GetDescriptor(const effect_uuid_t *uuid,
// This is the only symbol that needs to be exported
__attribute__ ((visibility ("default")))
audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
- tag : AUDIO_EFFECT_LIBRARY_TAG,
- version : EFFECT_LIBRARY_API_VERSION,
- name : "Audio Preprocessing Library",
- implementor : "The Android Open Source Project",
- create_effect : PreProcessingLib_Create,
- release_effect : PreProcessingLib_Release,
- get_descriptor : PreProcessingLib_GetDescriptor
+ .tag = AUDIO_EFFECT_LIBRARY_TAG,
+ .version = EFFECT_LIBRARY_API_VERSION,
+ .name = "Audio Preprocessing Library",
+ .implementor = "The Android Open Source Project",
+ .create_effect = PreProcessingLib_Create,
+ .release_effect = PreProcessingLib_Release,
+ .get_descriptor = PreProcessingLib_GetDescriptor
};
}; // extern "C"
diff --git a/media/libeffects/proxy/Android.mk b/media/libeffects/proxy/Android.mk
index a1894b7..b438796 100644
--- a/media/libeffects/proxy/Android.mk
+++ b/media/libeffects/proxy/Android.mk
@@ -15,7 +15,7 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE:= libeffectproxy
-LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/soundfx
+LOCAL_MODULE_RELATIVE_PATH := soundfx
LOCAL_MODULE_TAGS := optional
diff --git a/media/libeffects/proxy/EffectProxy.cpp b/media/libeffects/proxy/EffectProxy.cpp
index f93a143..62d3fd3 100644
--- a/media/libeffects/proxy/EffectProxy.cpp
+++ b/media/libeffects/proxy/EffectProxy.cpp
@@ -363,11 +363,11 @@ int Effect_getDescriptor(effect_handle_t self,
__attribute__ ((visibility ("default")))
audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
- tag : AUDIO_EFFECT_LIBRARY_TAG,
- version : EFFECT_LIBRARY_API_VERSION,
- name : "Effect Proxy",
- implementor : "AOSP",
- create_effect : android::EffectProxyCreate,
- release_effect : android::EffectProxyRelease,
- get_descriptor : android::EffectProxyGetDescriptor,
+ .tag = AUDIO_EFFECT_LIBRARY_TAG,
+ .version = EFFECT_LIBRARY_API_VERSION,
+ .name = "Effect Proxy",
+ .implementor = "AOSP",
+ .create_effect = android::EffectProxyCreate,
+ .release_effect = android::EffectProxyRelease,
+ .get_descriptor = android::EffectProxyGetDescriptor,
};
diff --git a/media/libeffects/testlibs/Android.mk_ b/media/libeffects/testlibs/Android.mk_
index 2954908..672ebba 100644
--- a/media/libeffects/testlibs/Android.mk_
+++ b/media/libeffects/testlibs/Android.mk_
@@ -11,7 +11,7 @@ LOCAL_CFLAGS+= -O2
LOCAL_SHARED_LIBRARIES := \
libcutils
-LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/soundfx
+LOCAL_MODULE_RELATIVE_PATH := soundfx
LOCAL_MODULE:= libreverbtest
ifeq ($(TARGET_OS)-$(TARGET_SIMULATOR),linux-true)
@@ -47,7 +47,7 @@ LOCAL_CFLAGS+= -O2
LOCAL_SHARED_LIBRARIES := \
libcutils
-LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/soundfx
+LOCAL_MODULE_RELATIVE_PATH := soundfx
LOCAL_MODULE:= libequalizertest
ifeq ($(TARGET_OS)-$(TARGET_SIMULATOR),linux-true)
diff --git a/media/libeffects/visualizer/Android.mk b/media/libeffects/visualizer/Android.mk
index e196eb2..dd2d306 100644
--- a/media/libeffects/visualizer/Android.mk
+++ b/media/libeffects/visualizer/Android.mk
@@ -13,7 +13,7 @@ LOCAL_SHARED_LIBRARIES := \
liblog \
libdl
-LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/soundfx
+LOCAL_MODULE_RELATIVE_PATH := soundfx
LOCAL_MODULE:= libvisualizer
LOCAL_C_INCLUDES := \
diff --git a/media/libeffects/visualizer/EffectVisualizer.cpp b/media/libeffects/visualizer/EffectVisualizer.cpp
index 18bdb78..4b318c0 100644
--- a/media/libeffects/visualizer/EffectVisualizer.cpp
+++ b/media/libeffects/visualizer/EffectVisualizer.cpp
@@ -679,13 +679,13 @@ const struct effect_interface_s gVisualizerInterface = {
// This is the only symbol that needs to be exported
__attribute__ ((visibility ("default")))
audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
- tag : AUDIO_EFFECT_LIBRARY_TAG,
- version : EFFECT_LIBRARY_API_VERSION,
- name : "Visualizer Library",
- implementor : "The Android Open Source Project",
- create_effect : VisualizerLib_Create,
- release_effect : VisualizerLib_Release,
- get_descriptor : VisualizerLib_GetDescriptor,
+ .tag = AUDIO_EFFECT_LIBRARY_TAG,
+ .version = EFFECT_LIBRARY_API_VERSION,
+ .name = "Visualizer Library",
+ .implementor = "The Android Open Source Project",
+ .create_effect = VisualizerLib_Create,
+ .release_effect = VisualizerLib_Release,
+ .get_descriptor = VisualizerLib_GetDescriptor,
};
}; // extern "C"
diff --git a/media/libmedia/AudioParameter.cpp b/media/libmedia/AudioParameter.cpp
index e3fea77..33dbf0b 100644
--- a/media/libmedia/AudioParameter.cpp
+++ b/media/libmedia/AudioParameter.cpp
@@ -37,9 +37,10 @@ AudioParameter::AudioParameter(const String8& keyValuePairs)
{
char *str = new char[keyValuePairs.length()+1];
mKeyValuePairs = keyValuePairs;
+ char *last;
strcpy(str, keyValuePairs.string());
- char *pair = strtok(str, ";");
+ char *pair = strtok_r(str, ";", &last);
while (pair != NULL) {
if (strlen(pair) != 0) {
size_t eqIdx = strcspn(pair, "=");
@@ -58,7 +59,7 @@ AudioParameter::AudioParameter(const String8& keyValuePairs)
} else {
ALOGV("AudioParameter() cstor empty key value pair");
}
- pair = strtok(NULL, ";");
+ pair = strtok_r(NULL, ";", &last);
}
delete[] str;
diff --git a/media/libmedia/IDrm.cpp b/media/libmedia/IDrm.cpp
index f7a9a75..f1a6a9f 100644
--- a/media/libmedia/IDrm.cpp
+++ b/media/libmedia/IDrm.cpp
@@ -51,6 +51,7 @@ enum {
ENCRYPT,
DECRYPT,
SIGN,
+ SIGN_RSA,
VERIFY,
SET_LISTENER
};
@@ -196,11 +197,15 @@ struct BpDrm : public BpInterface<IDrm> {
return reply.readInt32();
}
- virtual status_t getProvisionRequest(Vector<uint8_t> &request,
+ virtual status_t getProvisionRequest(String8 const &certType,
+ String8 const &certAuthority,
+ Vector<uint8_t> &request,
String8 &defaultUrl) {
Parcel data, reply;
data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
+ data.writeString8(certType);
+ data.writeString8(certAuthority);
remote()->transact(GET_PROVISION_REQUEST, data, &reply);
readVector(reply, request);
@@ -209,13 +214,18 @@ struct BpDrm : public BpInterface<IDrm> {
return reply.readInt32();
}
- virtual status_t provideProvisionResponse(Vector<uint8_t> const &response) {
+ virtual status_t provideProvisionResponse(Vector<uint8_t> const &response,
+ Vector<uint8_t> &certificate,
+ Vector<uint8_t> &wrappedKey) {
Parcel data, reply;
data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
writeVector(data, response);
remote()->transact(PROVIDE_PROVISION_RESPONSE, data, &reply);
+ readVector(reply, certificate);
+ readVector(reply, wrappedKey);
+
return reply.readInt32();
}
@@ -386,6 +396,25 @@ struct BpDrm : public BpInterface<IDrm> {
return reply.readInt32();
}
+ virtual status_t signRSA(Vector<uint8_t> const &sessionId,
+ String8 const &algorithm,
+ Vector<uint8_t> const &message,
+ Vector<uint8_t> const &wrappedKey,
+ Vector<uint8_t> &signature) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
+
+ writeVector(data, sessionId);
+ data.writeString8(algorithm);
+ writeVector(data, message);
+ writeVector(data, wrappedKey);
+
+ remote()->transact(SIGN_RSA, data, &reply);
+ readVector(reply, signature);
+
+ return reply.readInt32();
+ }
+
virtual status_t setListener(const sp<IDrmClient>& listener) {
Parcel data, reply;
data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
@@ -563,9 +592,13 @@ status_t BnDrm::onTransact(
case GET_PROVISION_REQUEST:
{
CHECK_INTERFACE(IDrm, data, reply);
+ String8 certType = data.readString8();
+ String8 certAuthority = data.readString8();
+
Vector<uint8_t> request;
String8 defaultUrl;
- status_t result = getProvisionRequest(request, defaultUrl);
+ status_t result = getProvisionRequest(certType, certAuthority,
+ request, defaultUrl);
writeVector(reply, request);
reply->writeString8(defaultUrl);
reply->writeInt32(result);
@@ -576,8 +609,13 @@ status_t BnDrm::onTransact(
{
CHECK_INTERFACE(IDrm, data, reply);
Vector<uint8_t> response;
+ Vector<uint8_t> certificate;
+ Vector<uint8_t> wrappedKey;
readVector(data, response);
- reply->writeInt32(provideProvisionResponse(response));
+ status_t result = provideProvisionResponse(response, certificate, wrappedKey);
+ writeVector(reply, certificate);
+ writeVector(reply, wrappedKey);
+ reply->writeInt32(result);
return OK;
}
@@ -725,6 +763,20 @@ status_t BnDrm::onTransact(
return OK;
}
+ case SIGN_RSA:
+ {
+ CHECK_INTERFACE(IDrm, data, reply);
+ Vector<uint8_t> sessionId, message, wrappedKey, signature;
+ readVector(data, sessionId);
+ String8 algorithm = data.readString8();
+ readVector(data, message);
+ readVector(data, wrappedKey);
+ uint32_t result = signRSA(sessionId, algorithm, message, wrappedKey, signature);
+ writeVector(reply, signature);
+ reply->writeInt32(result);
+ return OK;
+ }
+
case SET_LISTENER: {
CHECK_INTERFACE(IDrm, data, reply);
sp<IDrmClient> listener =
diff --git a/media/libmedia/MemoryLeakTrackUtil.cpp b/media/libmedia/MemoryLeakTrackUtil.cpp
index 6a108ae..f004ca4 100644
--- a/media/libmedia/MemoryLeakTrackUtil.cpp
+++ b/media/libmedia/MemoryLeakTrackUtil.cpp
@@ -49,7 +49,7 @@ struct MyString8 {
}
void append(const char *s) {
- strcat(mPtr, s);
+ strncat(mPtr, s, MAX_SIZE - size() - 1);
}
const char *string() const {
@@ -60,6 +60,10 @@ struct MyString8 {
return strlen(mPtr);
}
+ void clear() {
+ *mPtr = '\0';
+ }
+
private:
char *mPtr;
@@ -139,6 +143,9 @@ void dumpMemoryAddresses(int fd)
}
} while (moved);
+ write(fd, result.string(), result.size());
+ result.clear();
+
for (size_t i = 0; i < count; i++) {
AllocEntry *e = &entries[i];
@@ -152,13 +159,14 @@ void dumpMemoryAddresses(int fd)
result.append(buffer);
}
result.append("\n");
+
+ write(fd, result.string(), result.size());
+ result.clear();
}
delete[] entries;
free_malloc_leak_info(info);
}
-
- write(fd, result.string(), result.size());
}
#else
diff --git a/media/libmediaplayerservice/Drm.cpp b/media/libmediaplayerservice/Drm.cpp
index eebcb79..d50037f 100644
--- a/media/libmediaplayerservice/Drm.cpp
+++ b/media/libmediaplayerservice/Drm.cpp
@@ -28,9 +28,21 @@
#include <media/stagefright/foundation/AString.h>
#include <media/stagefright/foundation/hexdump.h>
#include <media/stagefright/MediaErrors.h>
+#include <binder/IServiceManager.h>
+#include <binder/IPCThreadState.h>
namespace android {
+static bool checkPermission(const char* permissionString) {
+#ifndef HAVE_ANDROID_OS
+ return true;
+#endif
+ if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
+ bool ok = checkCallingPermission(String16(permissionString));
+ if (!ok) ALOGE("Request requires %s", permissionString);
+ return ok;
+}
+
KeyedVector<Vector<uint8_t>, String8> Drm::mUUIDToLibraryPathMap;
KeyedVector<String8, wp<SharedLibrary> > Drm::mLibraryPathToOpenLibraryMap;
Mutex Drm::mMapLock;
@@ -373,7 +385,8 @@ status_t Drm::queryKeyStatus(Vector<uint8_t> const &sessionId,
return mPlugin->queryKeyStatus(sessionId, infoMap);
}
-status_t Drm::getProvisionRequest(Vector<uint8_t> &request, String8 &defaultUrl) {
+status_t Drm::getProvisionRequest(String8 const &certType, String8 const &certAuthority,
+ Vector<uint8_t> &request, String8 &defaultUrl) {
Mutex::Autolock autoLock(mLock);
if (mInitCheck != OK) {
@@ -384,10 +397,13 @@ status_t Drm::getProvisionRequest(Vector<uint8_t> &request, String8 &defaultUrl)
return -EINVAL;
}
- return mPlugin->getProvisionRequest(request, defaultUrl);
+ return mPlugin->getProvisionRequest(certType, certAuthority,
+ request, defaultUrl);
}
-status_t Drm::provideProvisionResponse(Vector<uint8_t> const &response) {
+status_t Drm::provideProvisionResponse(Vector<uint8_t> const &response,
+ Vector<uint8_t> &certificate,
+ Vector<uint8_t> &wrappedKey) {
Mutex::Autolock autoLock(mLock);
if (mInitCheck != OK) {
@@ -398,7 +414,7 @@ status_t Drm::provideProvisionResponse(Vector<uint8_t> const &response) {
return -EINVAL;
}
- return mPlugin->provideProvisionResponse(response);
+ return mPlugin->provideProvisionResponse(response, certificate, wrappedKey);
}
@@ -589,6 +605,28 @@ status_t Drm::verify(Vector<uint8_t> const &sessionId,
return mPlugin->verify(sessionId, keyId, message, signature, match);
}
+status_t Drm::signRSA(Vector<uint8_t> const &sessionId,
+ String8 const &algorithm,
+ Vector<uint8_t> const &message,
+ Vector<uint8_t> const &wrappedKey,
+ Vector<uint8_t> &signature) {
+ Mutex::Autolock autoLock(mLock);
+
+ if (mInitCheck != OK) {
+ return mInitCheck;
+ }
+
+ if (mPlugin == NULL) {
+ return -EINVAL;
+ }
+
+ if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
+ return -EPERM;
+ }
+
+ return mPlugin->signRSA(sessionId, algorithm, message, wrappedKey, signature);
+}
+
void Drm::binderDied(const wp<IBinder> &the_late_who)
{
delete mPlugin;
diff --git a/media/libmediaplayerservice/Drm.h b/media/libmediaplayerservice/Drm.h
index 119fd50..3d4b0fc 100644
--- a/media/libmediaplayerservice/Drm.h
+++ b/media/libmediaplayerservice/Drm.h
@@ -66,10 +66,14 @@ struct Drm : public BnDrm,
virtual status_t queryKeyStatus(Vector<uint8_t> const &sessionId,
KeyedVector<String8, String8> &infoMap) const;
- virtual status_t getProvisionRequest(Vector<uint8_t> &request,
+ virtual status_t getProvisionRequest(String8 const &certType,
+ String8 const &certAuthority,
+ Vector<uint8_t> &request,
String8 &defaulUrl);
- virtual status_t provideProvisionResponse(Vector<uint8_t> const &response);
+ virtual status_t provideProvisionResponse(Vector<uint8_t> const &response,
+ Vector<uint8_t> &certificate,
+ Vector<uint8_t> &wrappedKey);
virtual status_t getSecureStops(List<Vector<uint8_t> > &secureStops);
@@ -111,6 +115,12 @@ struct Drm : public BnDrm,
Vector<uint8_t> const &signature,
bool &match);
+ virtual status_t signRSA(Vector<uint8_t> const &sessionId,
+ String8 const &algorithm,
+ Vector<uint8_t> const &message,
+ Vector<uint8_t> const &wrappedKey,
+ Vector<uint8_t> &signature);
+
virtual status_t setListener(const sp<IDrmClient>& listener);
virtual void sendEvent(DrmPlugin::EventType eventType, int extra,
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index f710b55..25d55a3 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -32,6 +32,8 @@
#include "ATSParser.h"
+#include "SoftwareRenderer.h"
+
#include <cutils/properties.h> // for property_get
#include <media/stagefright/foundation/hexdump.h>
#include <media/stagefright/foundation/ABuffer.h>
@@ -146,6 +148,7 @@ NuPlayer::NuPlayer()
: mUIDValid(false),
mSourceFlags(0),
mVideoIsAVC(false),
+ mNeedsSwRenderer(false),
mAudioEOS(false),
mVideoEOS(false),
mScanSourcesPending(false),
@@ -444,6 +447,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
ALOGV("kWhatStart");
mVideoIsAVC = false;
+ mNeedsSwRenderer = false;
mAudioEOS = false;
mVideoEOS = false;
mSkipRenderingAudioUntilMediaTimeUs = -1;
@@ -680,6 +684,20 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
notifyListener(
MEDIA_SET_VIDEO_SIZE, displayWidth, displayHeight);
+
+ if (mNeedsSwRenderer && mNativeWindow != NULL) {
+ int32_t colorFormat;
+ CHECK(codecRequest->findInt32("color-format", &colorFormat));
+
+ sp<MetaData> meta = new MetaData;
+ meta->setInt32(kKeyWidth, width);
+ meta->setInt32(kKeyHeight, height);
+ meta->setRect(kKeyCropRect, cropLeft, cropTop, cropRight, cropBottom);
+ meta->setInt32(kKeyColorFormat, colorFormat);
+
+ mRenderer->setSoftRenderer(
+ new SoftwareRenderer(mNativeWindow->getNativeWindow(), meta));
+ }
}
} else if (what == ACodec::kWhatShutdownCompleted) {
ALOGV("%s shutdown completed", audio ? "audio" : "video");
@@ -703,8 +721,13 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
mRenderer->queueEOS(audio, UNKNOWN_ERROR);
} else if (what == ACodec::kWhatDrainThisBuffer) {
renderBuffer(audio, codecRequest);
- } else if (what != ACodec::kWhatComponentAllocated
- && what != ACodec::kWhatComponentConfigured
+ } else if (what == ACodec::kWhatComponentAllocated) {
+ if (!audio) {
+ AString name;
+ CHECK(codecRequest->findString("componentName", &name));
+ mNeedsSwRenderer = name.startsWith("OMX.google.");
+ }
+ } else if (what != ACodec::kWhatComponentConfigured
&& what != ACodec::kWhatBuffersAllocated) {
ALOGV("Unhandled codec notification %d '%c%c%c%c'.",
what,
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index 13350f3..590e1f2 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -116,6 +116,7 @@ private:
sp<MediaPlayerBase::AudioSink> mAudioSink;
sp<Decoder> mVideoDecoder;
bool mVideoIsAVC;
+ bool mNeedsSwRenderer;
sp<Decoder> mAudioDecoder;
sp<Renderer> mRenderer;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index 3b2784b..bf5271e 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -20,6 +20,8 @@
#include "NuPlayerRenderer.h"
+#include "SoftwareRenderer.h"
+
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
@@ -34,6 +36,7 @@ NuPlayer::Renderer::Renderer(
const sp<AMessage> &notify,
uint32_t flags)
: mAudioSink(sink),
+ mSoftRenderer(NULL),
mNotify(notify),
mFlags(flags),
mNumFramesWritten(0),
@@ -57,6 +60,12 @@ NuPlayer::Renderer::Renderer(
}
NuPlayer::Renderer::~Renderer() {
+ delete mSoftRenderer;
+}
+
+void NuPlayer::Renderer::setSoftRenderer(SoftwareRenderer *softRenderer) {
+ delete mSoftRenderer;
+ mSoftRenderer = softRenderer;
}
void NuPlayer::Renderer::queueBuffer(
@@ -413,7 +422,12 @@ void NuPlayer::Renderer::onDrainVideoQueue() {
ALOGV("video late by %lld us (%.2f secs)",
mVideoLateByUs, mVideoLateByUs / 1E6);
} else {
- ALOGV("rendering video at media time %.2f secs", mediaTimeUs / 1E6);
+ ALOGV("rendering video at media time %.2f secs",
+ (mFlags & FLAG_REAL_TIME ? realTimeUs :
+ (realTimeUs + mAnchorTimeMediaUs - mAnchorTimeRealUs)) / 1E6);
+ if (mSoftRenderer != NULL) {
+ mSoftRenderer->render(entry->mBuffer->data(), entry->mBuffer->size(), NULL);
+ }
}
entry->mNotifyConsumed->setInt32("render", !tooLate);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
index 94a05ea..9124e03 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
@@ -23,6 +23,7 @@
namespace android {
struct ABuffer;
+class SoftwareRenderer;
struct NuPlayer::Renderer : public AHandler {
enum Flags {
@@ -56,6 +57,8 @@ struct NuPlayer::Renderer : public AHandler {
kWhatMediaRenderingStart = 'mdrd',
};
+ void setSoftRenderer(SoftwareRenderer *softRenderer);
+
protected:
virtual ~Renderer();
@@ -83,6 +86,7 @@ private:
static const int64_t kMinPositionUpdateDelayUs;
sp<MediaPlayerBase::AudioSink> mAudioSink;
+ SoftwareRenderer *mSoftRenderer;
sp<AMessage> mNotify;
uint32_t mFlags;
List<QueueEntry> mAudioQueue;
diff --git a/media/libnbaio/MonoPipe.cpp b/media/libnbaio/MonoPipe.cpp
index de0ad28..3c61b60 100644
--- a/media/libnbaio/MonoPipe.cpp
+++ b/media/libnbaio/MonoPipe.cpp
@@ -183,7 +183,7 @@ ssize_t MonoPipe::write(const void *buffer, size_t count)
}
}
if (ns > 0) {
- const struct timespec req = {0, ns};
+ const struct timespec req = {0, static_cast<long>(ns)};
nanosleep(&req, NULL);
}
// record the time that this write() completed
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 718e6c7..67a19cd 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -35,7 +35,9 @@
#include <media/hardware/HardwareAPI.h>
+#include <OMX_AudioExt.h>
#include <OMX_Component.h>
+#include <OMX_IndexExt.h>
#include "include/avc_utils.h"
@@ -990,6 +992,10 @@ status_t ACodec::setComponentRole(
"audio_decoder.flac", "audio_encoder.flac" },
{ MEDIA_MIMETYPE_AUDIO_MSGSM,
"audio_decoder.gsm", "audio_encoder.gsm" },
+ { MEDIA_MIMETYPE_VIDEO_MPEG2,
+ "video_decoder.mpeg2", "video_encoder.mpeg2" },
+ { MEDIA_MIMETYPE_AUDIO_AC3,
+ "audio_decoder.ac3", "audio_encoder.ac3" },
};
static const size_t kNumMimeToRole =
@@ -1288,6 +1294,15 @@ status_t ACodec::configureCodec(
} else {
err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
}
+ } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
+ int32_t numChannels;
+ int32_t sampleRate;
+ if (!msg->findInt32("channel-count", &numChannels)
+ || !msg->findInt32("sample-rate", &sampleRate)) {
+ err = INVALID_OPERATION;
+ } else {
+ err = setupAC3Codec(encoder, numChannels, sampleRate);
+ }
}
if (err != OK) {
@@ -1484,6 +1499,44 @@ status_t ACodec::setupAACCodec(
mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
}
+status_t ACodec::setupAC3Codec(
+ bool encoder, int32_t numChannels, int32_t sampleRate) {
+ status_t err = setupRawAudioFormat(
+ encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
+
+ if (err != OK) {
+ return err;
+ }
+
+ if (encoder) {
+ ALOGW("AC3 encoding is not supported.");
+ return INVALID_OPERATION;
+ }
+
+ OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
+ InitOMXParams(&def);
+ def.nPortIndex = kPortIndexInput;
+
+ err = mOMX->getParameter(
+ mNode,
+ (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
+ &def,
+ sizeof(def));
+
+ if (err != OK) {
+ return err;
+ }
+
+ def.nChannels = numChannels;
+ def.nSampleRate = sampleRate;
+
+ return mOMX->setParameter(
+ mNode,
+ (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
+ &def,
+ sizeof(def));
+}
+
static OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
bool isAMRWB, int32_t bps) {
if (isAMRWB) {
@@ -2578,7 +2631,7 @@ void ACodec::sendFormatChange(const sp<AMessage> &reply) {
{
OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
- switch (audioDef->eEncoding) {
+ switch ((int)audioDef->eEncoding) {
case OMX_AUDIO_CodingPCM:
{
OMX_AUDIO_PARAM_PCMMODETYPE params;
@@ -2684,6 +2737,24 @@ void ACodec::sendFormatChange(const sp<AMessage> &reply) {
break;
}
+ case OMX_AUDIO_CodingAndroidAC3:
+ {
+ OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
+ InitOMXParams(&params);
+ params.nPortIndex = kPortIndexOutput;
+
+ CHECK_EQ((status_t)OK, mOMX->getParameter(
+ mNode,
+ (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
+ &params,
+ sizeof(params)));
+
+ notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
+ notify->setInt32("channel-count", params.nChannels);
+ notify->setInt32("sample-rate", params.nSampleRate);
+ break;
+ }
+
default:
TRESPASS();
}
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 130207d..aae6800 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -2096,7 +2096,10 @@ void AwesomePlayer::onCheckAudioStatus() {
mSeekNotificationSent = true;
}
- mSeeking = NO_SEEK;
+ if (mVideoSource == NULL) {
+ // For video the mSeeking flag is always reset in finishSeekIfNecessary
+ mSeeking = NO_SEEK;
+ }
notifyIfMediaStarted_l();
}
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 92065d1..e9ecc45 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -39,6 +39,9 @@
#include <media/stagefright/MetaData.h>
#include <utils/String8.h>
+#include <byteswap.h>
+#include "include/ID3.h"
+
#ifndef UINT32_MAX
#define UINT32_MAX (4294967295U)
#endif
@@ -689,7 +692,7 @@ status_t MPEG4Extractor::parseDrmSINF(off64_t *offset, off64_t data_offset) {
}
data_offset += 2;
- if (mDataSource->readAt(data_offset + 2, sinf->IPMPData, sinf->len) < sinf->len) {
+ if (mDataSource->readAt(data_offset, sinf->IPMPData, sinf->len) < sinf->len) {
return ERROR_IO;
}
data_offset += sinf->len;
@@ -1658,7 +1661,7 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
case FOURCC('d', 'a', 't', 'a'):
{
if (mPath.size() == 6 && underMetaDataPath(mPath)) {
- status_t err = parseMetaData(data_offset, chunk_data_size);
+ status_t err = parseITunesMetaData(data_offset, chunk_data_size);
if (err != OK) {
return err;
@@ -1804,6 +1807,35 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
break;
}
+ case FOURCC('t', 'i', 't', 'l'):
+ case FOURCC('p', 'e', 'r', 'f'):
+ case FOURCC('a', 'u', 't', 'h'):
+ case FOURCC('g', 'n', 'r', 'e'):
+ case FOURCC('a', 'l', 'b', 'm'):
+ case FOURCC('y', 'r', 'r', 'c'):
+ {
+ status_t err = parse3GPPMetaData(data_offset, chunk_data_size, depth);
+
+ if (err != OK) {
+ return err;
+ }
+
+ *offset += chunk_size;
+ break;
+ }
+
+ case FOURCC('I', 'D', '3', '2'):
+ {
+ if (chunk_data_size < 6) {
+ return ERROR_MALFORMED;
+ }
+
+ parseID3v2MetaData(data_offset + 6);
+
+ *offset += chunk_size;
+ break;
+ }
+
case FOURCC('-', '-', '-', '-'):
{
mLastCommentMean.clear();
@@ -2038,7 +2070,7 @@ status_t MPEG4Extractor::parseTrackHeader(
return OK;
}
-status_t MPEG4Extractor::parseMetaData(off64_t offset, size_t size) {
+status_t MPEG4Extractor::parseITunesMetaData(off64_t offset, size_t size) {
if (size < 4 || size == SIZE_MAX) {
return ERROR_MALFORMED;
}
@@ -2187,7 +2219,7 @@ status_t MPEG4Extractor::parseMetaData(off64_t offset, size_t size) {
break;
}
- if (size >= 8 && metadataKey) {
+ if (size >= 8 && metadataKey && !mFileMetaData->hasData(metadataKey)) {
if (metadataKey == kKeyAlbumArt) {
mFileMetaData->setData(
kKeyAlbumArt, MetaData::TYPE_NONE,
@@ -2228,6 +2260,170 @@ status_t MPEG4Extractor::parseMetaData(off64_t offset, size_t size) {
return OK;
}
+status_t MPEG4Extractor::parse3GPPMetaData(off64_t offset, size_t size, int depth) {
+ if (size < 4) {
+ return ERROR_MALFORMED;
+ }
+
+ uint8_t *buffer = new uint8_t[size];
+ if (mDataSource->readAt(
+ offset, buffer, size) != (ssize_t)size) {
+ delete[] buffer;
+ buffer = NULL;
+
+ return ERROR_IO;
+ }
+
+ uint32_t metadataKey = 0;
+ switch (mPath[depth]) {
+ case FOURCC('t', 'i', 't', 'l'):
+ {
+ metadataKey = kKeyTitle;
+ break;
+ }
+ case FOURCC('p', 'e', 'r', 'f'):
+ {
+ metadataKey = kKeyArtist;
+ break;
+ }
+ case FOURCC('a', 'u', 't', 'h'):
+ {
+ metadataKey = kKeyWriter;
+ break;
+ }
+ case FOURCC('g', 'n', 'r', 'e'):
+ {
+ metadataKey = kKeyGenre;
+ break;
+ }
+ case FOURCC('a', 'l', 'b', 'm'):
+ {
+ if (buffer[size - 1] != '\0') {
+ char tmp[4];
+ sprintf(tmp, "%u", buffer[size - 1]);
+
+ mFileMetaData->setCString(kKeyCDTrackNumber, tmp);
+ }
+
+ metadataKey = kKeyAlbum;
+ break;
+ }
+ case FOURCC('y', 'r', 'r', 'c'):
+ {
+ char tmp[5];
+ uint16_t year = U16_AT(&buffer[4]);
+
+ if (year < 10000) {
+ sprintf(tmp, "%u", year);
+
+ mFileMetaData->setCString(kKeyYear, tmp);
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ if (metadataKey > 0) {
+ bool isUTF8 = true; // Common case
+ char16_t *framedata = NULL;
+ int len16 = 0; // Number of UTF-16 characters
+
+ // smallest possible valid UTF-16 string w BOM: 0xfe 0xff 0x00 0x00
+ if (size - 6 >= 4) {
+ len16 = ((size - 6) / 2) - 1; // don't include 0x0000 terminator
+ framedata = (char16_t *)(buffer + 6);
+ if (0xfffe == *framedata) {
+ // endianness marker (BOM) doesn't match host endianness
+ for (int i = 0; i < len16; i++) {
+ framedata[i] = bswap_16(framedata[i]);
+ }
+ // BOM is now swapped to 0xfeff, we will execute next block too
+ }
+
+ if (0xfeff == *framedata) {
+ // Remove the BOM
+ framedata++;
+ len16--;
+ isUTF8 = false;
+ }
+ // else normal non-zero-length UTF-8 string
+ // we can't handle UTF-16 without BOM as there is no other
+ // indication of encoding.
+ }
+
+ if (isUTF8) {
+ mFileMetaData->setCString(metadataKey, (const char *)buffer + 6);
+ } else {
+ // Convert from UTF-16 string to UTF-8 string.
+ String8 tmpUTF8str(framedata, len16);
+ mFileMetaData->setCString(metadataKey, tmpUTF8str.string());
+ }
+ }
+
+ delete[] buffer;
+ buffer = NULL;
+
+ return OK;
+}
+
+void MPEG4Extractor::parseID3v2MetaData(off64_t offset) {
+ ID3 id3(mDataSource, true /* ignorev1 */, offset);
+
+ if (id3.isValid()) {
+ struct Map {
+ int key;
+ const char *tag1;
+ const char *tag2;
+ };
+ static const Map kMap[] = {
+ { kKeyAlbum, "TALB", "TAL" },
+ { kKeyArtist, "TPE1", "TP1" },
+ { kKeyAlbumArtist, "TPE2", "TP2" },
+ { kKeyComposer, "TCOM", "TCM" },
+ { kKeyGenre, "TCON", "TCO" },
+ { kKeyTitle, "TIT2", "TT2" },
+ { kKeyYear, "TYE", "TYER" },
+ { kKeyAuthor, "TXT", "TEXT" },
+ { kKeyCDTrackNumber, "TRK", "TRCK" },
+ { kKeyDiscNumber, "TPA", "TPOS" },
+ { kKeyCompilation, "TCP", "TCMP" },
+ };
+ static const size_t kNumMapEntries = sizeof(kMap) / sizeof(kMap[0]);
+
+ for (size_t i = 0; i < kNumMapEntries; ++i) {
+ if (!mFileMetaData->hasData(kMap[i].key)) {
+ ID3::Iterator *it = new ID3::Iterator(id3, kMap[i].tag1);
+ if (it->done()) {
+ delete it;
+ it = new ID3::Iterator(id3, kMap[i].tag2);
+ }
+
+ if (it->done()) {
+ delete it;
+ continue;
+ }
+
+ String8 s;
+ it->getString(&s);
+ delete it;
+
+ mFileMetaData->setCString(kMap[i].key, s);
+ }
+ }
+
+ size_t dataSize;
+ String8 mime;
+ const void *data = id3.getAlbumArt(&dataSize, &mime);
+
+ if (data) {
+ mFileMetaData->setData(kKeyAlbumArt, MetaData::TYPE_NONE, data, dataSize);
+ mFileMetaData->setCString(kKeyAlbumArtMIME, mime.string());
+ }
+ }
+}
+
sp<MediaSource> MPEG4Extractor::getTrack(size_t index) {
status_t err;
if ((err = readMetaData()) != OK) {
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index c36dd7c..8af1aaf 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -746,6 +746,10 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
CHECK(msg->findInt32("width", &width));
CHECK(msg->findInt32("height", &height));
+ int32_t cropLeft, cropTop, cropRight, cropBottom;
+ CHECK(msg->findRect("crop",
+ &cropLeft, &cropTop, &cropRight, &cropBottom));
+
int32_t colorFormat;
CHECK(msg->findInt32(
"color-format", &colorFormat));
@@ -753,6 +757,8 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
sp<MetaData> meta = new MetaData;
meta->setInt32(kKeyWidth, width);
meta->setInt32(kKeyHeight, height);
+ meta->setRect(kKeyCropRect,
+ cropLeft, cropTop, cropRight, cropBottom);
meta->setInt32(kKeyColorFormat, colorFormat);
mSoftRenderer =
diff --git a/media/libstagefright/MediaCodecList.cpp b/media/libstagefright/MediaCodecList.cpp
index 6248e90..b74b2e2 100644
--- a/media/libstagefright/MediaCodecList.cpp
+++ b/media/libstagefright/MediaCodecList.cpp
@@ -57,15 +57,6 @@ MediaCodecList::MediaCodecList()
parseXMLFile(file);
- if (mInitCheck == OK) {
- // These are currently still used by the video editing suite.
-
- addMediaCodec(true /* encoder */, "AACEncoder", "audio/mp4a-latm");
-
- addMediaCodec(
- false /* encoder */, "OMX.google.raw.decoder", "audio/raw");
- }
-
#if 0
for (size_t i = 0; i < mCodecInfos.size(); ++i) {
const CodecInfo &info = mCodecInfos.itemAt(i);
diff --git a/media/libstagefright/MediaDefs.cpp b/media/libstagefright/MediaDefs.cpp
index b5d4e44..340cba7 100644
--- a/media/libstagefright/MediaDefs.cpp
+++ b/media/libstagefright/MediaDefs.cpp
@@ -42,6 +42,7 @@ const char *MEDIA_MIMETYPE_AUDIO_RAW = "audio/raw";
const char *MEDIA_MIMETYPE_AUDIO_FLAC = "audio/flac";
const char *MEDIA_MIMETYPE_AUDIO_AAC_ADTS = "audio/aac-adts";
const char *MEDIA_MIMETYPE_AUDIO_MSGSM = "audio/gsm";
+const char *MEDIA_MIMETYPE_AUDIO_AC3 = "audio/ac3";
const char *MEDIA_MIMETYPE_CONTAINER_MPEG4 = "video/mp4";
const char *MEDIA_MIMETYPE_CONTAINER_WAV = "audio/x-wav";
diff --git a/media/libstagefright/MetaData.cpp b/media/libstagefright/MetaData.cpp
index 2264a23..725f97e 100644
--- a/media/libstagefright/MetaData.cpp
+++ b/media/libstagefright/MetaData.cpp
@@ -221,6 +221,16 @@ bool MetaData::findData(uint32_t key, uint32_t *type,
return true;
}
+bool MetaData::hasData(uint32_t key) const {
+ ssize_t i = mItems.indexOfKey(key);
+
+ if (i < 0) {
+ return false;
+ }
+
+ return true;
+}
+
MetaData::typed_data::typed_data()
: mType(0),
mSize(0) {
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 43736ad..625922f 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -40,7 +40,9 @@
#include <utils/Vector.h>
#include <OMX_Audio.h>
+#include <OMX_AudioExt.h>
#include <OMX_Component.h>
+#include <OMX_IndexExt.h>
#include "include/avc_utils.h"
@@ -528,6 +530,17 @@ status_t OMXCodec::configureCodec(const sp<MetaData> &meta) {
sampleRate,
numChannels);
}
+ } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AC3, mMIME)) {
+ int32_t numChannels;
+ int32_t sampleRate;
+ CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
+ CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
+
+ status_t err = setAC3Format(numChannels, sampleRate);
+ if (err != OK) {
+ CODEC_LOGE("setAC3Format() failed (err = %d)", err);
+ return err;
+ }
} else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_G711_ALAW, mMIME)
|| !strcasecmp(MEDIA_MIMETYPE_AUDIO_G711_MLAW, mMIME)) {
// These are PCM-like formats with a fixed sample rate but
@@ -1394,6 +1407,10 @@ void OMXCodec::setComponentRole(
"audio_decoder.flac", "audio_encoder.flac" },
{ MEDIA_MIMETYPE_AUDIO_MSGSM,
"audio_decoder.gsm", "audio_encoder.gsm" },
+ { MEDIA_MIMETYPE_VIDEO_MPEG2,
+ "video_decoder.mpeg2", "video_encoder.mpeg2" },
+ { MEDIA_MIMETYPE_AUDIO_AC3,
+ "audio_decoder.ac3", "audio_encoder.ac3" },
};
static const size_t kNumMimeToRole =
@@ -3489,6 +3506,31 @@ status_t OMXCodec::setAACFormat(
return OK;
}
+status_t OMXCodec::setAC3Format(int32_t numChannels, int32_t sampleRate) {
+ OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
+ InitOMXParams(&def);
+ def.nPortIndex = kPortIndexInput;
+
+ status_t err = mOMX->getParameter(
+ mNode,
+ (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
+ &def,
+ sizeof(def));
+
+ if (err != OK) {
+ return err;
+ }
+
+ def.nChannels = numChannels;
+ def.nSampleRate = sampleRate;
+
+ return mOMX->setParameter(
+ mNode,
+ (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
+ &def,
+ sizeof(def));
+}
+
void OMXCodec::setG711Format(int32_t numChannels) {
CHECK(!mIsEncoder);
setRawAudioFormat(kPortIndexInput, 8000, numChannels);
@@ -4422,6 +4464,17 @@ void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) {
mOutputFormat->setInt32(kKeyChannelCount, numChannels);
mOutputFormat->setInt32(kKeySampleRate, sampleRate);
mOutputFormat->setInt32(kKeyBitRate, bitRate);
+ } else if (audio_def->eEncoding ==
+ (OMX_AUDIO_CODINGTYPE)OMX_AUDIO_CodingAndroidAC3) {
+ mOutputFormat->setCString(
+ kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AC3);
+ int32_t numChannels, sampleRate, bitRate;
+ inputFormat->findInt32(kKeyChannelCount, &numChannels);
+ inputFormat->findInt32(kKeySampleRate, &sampleRate);
+ inputFormat->findInt32(kKeyBitRate, &bitRate);
+ mOutputFormat->setInt32(kKeyChannelCount, numChannels);
+ mOutputFormat->setInt32(kKeySampleRate, sampleRate);
+ mOutputFormat->setInt32(kKeyBitRate, bitRate);
} else {
CHECK(!"Should not be here. Unknown audio encoding.");
}
diff --git a/media/libstagefright/TimedEventQueue.cpp b/media/libstagefright/TimedEventQueue.cpp
index dedd186..0afac69 100644
--- a/media/libstagefright/TimedEventQueue.cpp
+++ b/media/libstagefright/TimedEventQueue.cpp
@@ -318,7 +318,7 @@ sp<TimedEventQueue::Event> TimedEventQueue::removeEventFromQueue_l(
void TimedEventQueue::acquireWakeLock_l()
{
- if (mWakeLockCount++ == 0) {
+ if (mWakeLockCount == 0) {
CHECK(mWakeLockToken == 0);
if (mPowerManager == 0) {
// use checkService() to avoid blocking if power service is not up yet
@@ -341,21 +341,23 @@ void TimedEventQueue::acquireWakeLock_l()
IPCThreadState::self()->restoreCallingIdentity(token);
if (status == NO_ERROR) {
mWakeLockToken = binder;
+ mWakeLockCount++;
}
}
+ } else {
+ mWakeLockCount++;
}
}
void TimedEventQueue::releaseWakeLock_l(bool force)
{
+ if (mWakeLockCount == 0) {
+ return;
+ }
if (force) {
- if (mWakeLockCount == 0) {
- return;
- }
// Force wakelock release below by setting reference count to 1.
mWakeLockCount = 1;
}
- CHECK(mWakeLockCount != 0);
if (--mWakeLockCount == 0) {
CHECK(mWakeLockToken != 0);
if (mPowerManager != 0) {
diff --git a/media/libstagefright/WVMExtractor.cpp b/media/libstagefright/WVMExtractor.cpp
index 5ae80cc..bc48272 100644
--- a/media/libstagefright/WVMExtractor.cpp
+++ b/media/libstagefright/WVMExtractor.cpp
@@ -76,7 +76,7 @@ static void init_routine()
{
gVendorLibHandle = dlopen("libwvm.so", RTLD_NOW);
if (gVendorLibHandle == NULL) {
- ALOGE("Failed to open libwvm.so");
+ ALOGE("Failed to open libwvm.so: %s", dlerror());
}
}
diff --git a/media/libstagefright/codecs/avc/enc/SoftAVCEncoder.cpp b/media/libstagefright/codecs/avc/enc/SoftAVCEncoder.cpp
index 4e11628..e2b9e4f 100644
--- a/media/libstagefright/codecs/avc/enc/SoftAVCEncoder.cpp
+++ b/media/libstagefright/codecs/avc/enc/SoftAVCEncoder.cpp
@@ -887,7 +887,13 @@ void SoftAVCEncoder::onQueueFilled(OMX_U32 portIndex) {
CHECK(encoderStatus == AVCENC_SUCCESS || encoderStatus == AVCENC_NEW_IDR);
dataLength = outHeader->nAllocLen; // Reset the output buffer length
if (inHeader->nFilledLen > 0) {
+ if (outHeader->nAllocLen >= 4) {
+ memcpy(outPtr, "\x00\x00\x00\x01", 4);
+ outPtr += 4;
+ dataLength -= 4;
+ }
encoderStatus = PVAVCEncodeNAL(mHandle, outPtr, &dataLength, &type);
+ dataLength = outPtr + dataLength - outHeader->pBuffer;
if (encoderStatus == AVCENC_SUCCESS) {
CHECK(NULL == PVAVCEncGetOverrunBuffer(mHandle));
} else if (encoderStatus == AVCENC_PICTURE_READY) {
diff --git a/media/libstagefright/httplive/M3UParser.cpp b/media/libstagefright/httplive/M3UParser.cpp
index f211bc8..e31ad40 100644
--- a/media/libstagefright/httplive/M3UParser.cpp
+++ b/media/libstagefright/httplive/M3UParser.cpp
@@ -626,7 +626,7 @@ status_t M3UParser::parseMetaDataDuration(
if (meta->get() == NULL) {
*meta = new AMessage;
}
- (*meta)->setInt64(key, (int64_t)x * 1E6);
+ (*meta)->setInt64(key, (int64_t)(x * 1E6));
return OK;
}
diff --git a/media/libstagefright/id3/ID3.cpp b/media/libstagefright/id3/ID3.cpp
index 5a490e9..f2a8a73 100644
--- a/media/libstagefright/id3/ID3.cpp
+++ b/media/libstagefright/id3/ID3.cpp
@@ -56,14 +56,14 @@ private:
DISALLOW_EVIL_CONSTRUCTORS(MemorySource);
};
-ID3::ID3(const sp<DataSource> &source, bool ignoreV1)
+ID3::ID3(const sp<DataSource> &source, bool ignoreV1, off64_t offset)
: mIsValid(false),
mData(NULL),
mSize(0),
mFirstFrameOffset(0),
mVersion(ID3_UNKNOWN),
mRawSize(0) {
- mIsValid = parseV2(source);
+ mIsValid = parseV2(source, offset);
if (!mIsValid && !ignoreV1) {
mIsValid = parseV1(source);
@@ -79,7 +79,7 @@ ID3::ID3(const uint8_t *data, size_t size, bool ignoreV1)
mRawSize(0) {
sp<MemorySource> source = new MemorySource(data, size);
- mIsValid = parseV2(source);
+ mIsValid = parseV2(source, 0);
if (!mIsValid && !ignoreV1) {
mIsValid = parseV1(source);
@@ -115,7 +115,7 @@ bool ID3::ParseSyncsafeInteger(const uint8_t encoded[4], size_t *x) {
return true;
}
-bool ID3::parseV2(const sp<DataSource> &source) {
+bool ID3::parseV2(const sp<DataSource> &source, off64_t offset) {
struct id3_header {
char id[3];
uint8_t version_major;
@@ -126,7 +126,7 @@ struct id3_header {
id3_header header;
if (source->readAt(
- 0, &header, sizeof(header)) != (ssize_t)sizeof(header)) {
+ offset, &header, sizeof(header)) != (ssize_t)sizeof(header)) {
return false;
}
@@ -185,7 +185,7 @@ struct id3_header {
mSize = size;
mRawSize = mSize + sizeof(header);
- if (source->readAt(sizeof(header), mData, mSize) != (ssize_t)mSize) {
+ if (source->readAt(offset + sizeof(header), mData, mSize) != (ssize_t)mSize) {
free(mData);
mData = NULL;
diff --git a/media/libstagefright/include/ID3.h b/media/libstagefright/include/ID3.h
index cca83ab..e83f3ef 100644
--- a/media/libstagefright/include/ID3.h
+++ b/media/libstagefright/include/ID3.h
@@ -35,7 +35,7 @@ struct ID3 {
ID3_V2_4,
};
- ID3(const sp<DataSource> &source, bool ignoreV1 = false);
+ ID3(const sp<DataSource> &source, bool ignoreV1 = false, off64_t offset = 0);
ID3(const uint8_t *data, size_t size, bool ignoreV1 = false);
~ID3();
@@ -86,7 +86,7 @@ private:
size_t mRawSize;
bool parseV1(const sp<DataSource> &source);
- bool parseV2(const sp<DataSource> &source);
+ bool parseV2(const sp<DataSource> &source, off64_t offset);
void removeUnsynchronization();
bool removeUnsynchronizationV2_4(bool iTunesHack);
diff --git a/media/libstagefright/include/MPEG4Extractor.h b/media/libstagefright/include/MPEG4Extractor.h
index bbec1c4..7b4bc6d 100644
--- a/media/libstagefright/include/MPEG4Extractor.h
+++ b/media/libstagefright/include/MPEG4Extractor.h
@@ -95,7 +95,9 @@ private:
status_t readMetaData();
status_t parseChunk(off64_t *offset, int depth);
- status_t parseMetaData(off64_t offset, size_t size);
+ status_t parseITunesMetaData(off64_t offset, size_t size);
+ status_t parse3GPPMetaData(off64_t offset, size_t size, int depth);
+ void parseID3v2MetaData(off64_t offset);
status_t updateAudioTrackInfoFromESDS_MPEG4Audio(
const void *esds_data, size_t esds_size);
diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp
index 175a263..cb57a2f 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.cpp
+++ b/media/libstagefright/mpeg2ts/ATSParser.cpp
@@ -506,6 +506,11 @@ ATSParser::Stream::Stream(
ElementaryStreamQueue::PCM_AUDIO);
break;
+ case STREAMTYPE_AC3:
+ mQueue = new ElementaryStreamQueue(
+ ElementaryStreamQueue::AC3);
+ break;
+
default:
break;
}
@@ -614,6 +619,7 @@ bool ATSParser::Stream::isAudio() const {
case STREAMTYPE_MPEG2_AUDIO:
case STREAMTYPE_MPEG2_AUDIO_ADTS:
case STREAMTYPE_PCM_AUDIO:
+ case STREAMTYPE_AC3:
return true;
default:
diff --git a/media/libstagefright/mpeg2ts/ATSParser.h b/media/libstagefright/mpeg2ts/ATSParser.h
index 8a80069..86b025f 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.h
+++ b/media/libstagefright/mpeg2ts/ATSParser.h
@@ -89,6 +89,10 @@ struct ATSParser : public RefBase {
STREAMTYPE_MPEG2_AUDIO_ADTS = 0x0f,
STREAMTYPE_MPEG4_VIDEO = 0x10,
STREAMTYPE_H264 = 0x1b,
+
+ // From ATSC A/53 Part 3:2009, 6.7.1
+ STREAMTYPE_AC3 = 0x81,
+
STREAMTYPE_PCM_AUDIO = 0x83,
};
diff --git a/media/libstagefright/mpeg2ts/ESQueue.cpp b/media/libstagefright/mpeg2ts/ESQueue.cpp
index 8f9c9c8..2b0711b 100644
--- a/media/libstagefright/mpeg2ts/ESQueue.cpp
+++ b/media/libstagefright/mpeg2ts/ESQueue.cpp
@@ -56,6 +56,122 @@ void ElementaryStreamQueue::clear(bool clearFormat) {
}
}
+// Parse AC3 header assuming the current ptr is start position of syncframe,
+// update metadata only applicable, and return the payload size
+static unsigned parseAC3SyncFrame(
+ const uint8_t *ptr, size_t size, sp<MetaData> *metaData) {
+ static const unsigned channelCountTable[] = {2, 1, 2, 3, 3, 4, 4, 5};
+ static const unsigned samplingRateTable[] = {48000, 44100, 32000};
+ static const unsigned rates[] = {32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256,
+ 320, 384, 448, 512, 576, 640};
+
+ static const unsigned frameSizeTable[19][3] = {
+ { 64, 69, 96 },
+ { 80, 87, 120 },
+ { 96, 104, 144 },
+ { 112, 121, 168 },
+ { 128, 139, 192 },
+ { 160, 174, 240 },
+ { 192, 208, 288 },
+ { 224, 243, 336 },
+ { 256, 278, 384 },
+ { 320, 348, 480 },
+ { 384, 417, 576 },
+ { 448, 487, 672 },
+ { 512, 557, 768 },
+ { 640, 696, 960 },
+ { 768, 835, 1152 },
+ { 896, 975, 1344 },
+ { 1024, 1114, 1536 },
+ { 1152, 1253, 1728 },
+ { 1280, 1393, 1920 },
+ };
+
+ ABitReader bits(ptr, size);
+ unsigned syncStartPos = 0; // in bytes
+ if (bits.numBitsLeft() < 16) {
+ return 0;
+ }
+ if (bits.getBits(16) != 0x0B77) {
+ return 0;
+ }
+
+ if (bits.numBitsLeft() < 16 + 2 + 6 + 5 + 3 + 3) {
+ ALOGV("Not enough bits left for further parsing");
+ return 0;
+ }
+ bits.skipBits(16); // crc1
+
+ unsigned fscod = bits.getBits(2);
+ if (fscod == 3) {
+ ALOGW("Incorrect fscod in AC3 header");
+ return 0;
+ }
+
+ unsigned frmsizecod = bits.getBits(6);
+ if (frmsizecod > 37) {
+ ALOGW("Incorrect frmsizecod in AC3 header");
+ return 0;
+ }
+
+ unsigned bsid = bits.getBits(5);
+ if (bsid > 8) {
+ ALOGW("Incorrect bsid in AC3 header. Possibly E-AC-3?");
+ return 0;
+ }
+
+ unsigned bsmod = bits.getBits(3);
+ unsigned acmod = bits.getBits(3);
+ unsigned cmixlev = 0;
+ unsigned surmixlev = 0;
+ unsigned dsurmod = 0;
+
+ if ((acmod & 1) > 0 && acmod != 1) {
+ if (bits.numBitsLeft() < 2) {
+ return 0;
+ }
+ cmixlev = bits.getBits(2);
+ }
+ if ((acmod & 4) > 0) {
+ if (bits.numBitsLeft() < 2) {
+ return 0;
+ }
+ surmixlev = bits.getBits(2);
+ }
+ if (acmod == 2) {
+ if (bits.numBitsLeft() < 2) {
+ return 0;
+ }
+ dsurmod = bits.getBits(2);
+ }
+
+ if (bits.numBitsLeft() < 1) {
+ return 0;
+ }
+ unsigned lfeon = bits.getBits(1);
+
+ unsigned samplingRate = samplingRateTable[fscod];
+ unsigned payloadSize = frameSizeTable[frmsizecod >> 1][fscod];
+ if (fscod == 1) {
+ payloadSize += frmsizecod & 1;
+ }
+ payloadSize <<= 1; // convert from 16-bit words to bytes
+
+ unsigned channelCount = channelCountTable[acmod] + lfeon;
+
+ if (metaData != NULL) {
+ (*metaData)->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AC3);
+ (*metaData)->setInt32(kKeyChannelCount, channelCount);
+ (*metaData)->setInt32(kKeySampleRate, samplingRate);
+ }
+
+ return payloadSize;
+}
+
+static bool IsSeeminglyValidAC3Header(const uint8_t *ptr, size_t size) {
+ return parseAC3SyncFrame(ptr, size, NULL) > 0;
+}
+
static bool IsSeeminglyValidADTSHeader(const uint8_t *ptr, size_t size) {
if (size < 3) {
// Not enough data to verify header.
@@ -224,6 +340,33 @@ status_t ElementaryStreamQueue::appendData(
break;
}
+ case AC3:
+ {
+ uint8_t *ptr = (uint8_t *)data;
+
+ ssize_t startOffset = -1;
+ for (size_t i = 0; i < size; ++i) {
+ if (IsSeeminglyValidAC3Header(&ptr[i], size - i)) {
+ startOffset = i;
+ break;
+ }
+ }
+
+ if (startOffset < 0) {
+ return ERROR_MALFORMED;
+ }
+
+ if (startOffset > 0) {
+ ALOGI("found something resembling an AC3 syncword at "
+ "offset %d",
+ startOffset);
+ }
+
+ data = &ptr[startOffset];
+ size -= startOffset;
+ break;
+ }
+
case MPEG_AUDIO:
{
uint8_t *ptr = (uint8_t *)data;
@@ -328,6 +471,8 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnit() {
return dequeueAccessUnitH264();
case AAC:
return dequeueAccessUnitAAC();
+ case AC3:
+ return dequeueAccessUnitAC3();
case MPEG_VIDEO:
return dequeueAccessUnitMPEGVideo();
case MPEG4_VIDEO:
@@ -340,6 +485,51 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnit() {
}
}
+sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitAC3() {
+ unsigned syncStartPos = 0; // in bytes
+ unsigned payloadSize = 0;
+ sp<MetaData> format = new MetaData;
+ while (true) {
+ if (syncStartPos + 2 >= mBuffer->size()) {
+ return NULL;
+ }
+
+ payloadSize = parseAC3SyncFrame(
+ mBuffer->data() + syncStartPos,
+ mBuffer->size() - syncStartPos,
+ &format);
+ if (payloadSize > 0) {
+ break;
+ }
+ ++syncStartPos;
+ }
+
+ if (mBuffer->size() < syncStartPos + payloadSize) {
+ ALOGV("Not enough buffer size for AC3");
+ return NULL;
+ }
+
+ if (mFormat == NULL) {
+ mFormat = format;
+ }
+
+ sp<ABuffer> accessUnit = new ABuffer(syncStartPos + payloadSize);
+ memcpy(accessUnit->data(), mBuffer->data(), syncStartPos + payloadSize);
+
+ int64_t timeUs = fetchTimestamp(syncStartPos + payloadSize);
+ CHECK_GE(timeUs, 0ll);
+ accessUnit->meta()->setInt64("timeUs", timeUs);
+
+ memmove(
+ mBuffer->data(),
+ mBuffer->data() + syncStartPos + payloadSize,
+ mBuffer->size() - syncStartPos - payloadSize);
+
+ mBuffer->setRange(0, mBuffer->size() - syncStartPos - payloadSize);
+
+ return accessUnit;
+}
+
sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitPCMAudio() {
if (mBuffer->size() < 4) {
return NULL;
diff --git a/media/libstagefright/mpeg2ts/ESQueue.h b/media/libstagefright/mpeg2ts/ESQueue.h
index 66a8087..a2cca77 100644
--- a/media/libstagefright/mpeg2ts/ESQueue.h
+++ b/media/libstagefright/mpeg2ts/ESQueue.h
@@ -32,6 +32,7 @@ struct ElementaryStreamQueue {
enum Mode {
H264,
AAC,
+ AC3,
MPEG_AUDIO,
MPEG_VIDEO,
MPEG4_VIDEO,
@@ -67,6 +68,7 @@ private:
sp<ABuffer> dequeueAccessUnitH264();
sp<ABuffer> dequeueAccessUnitAAC();
+ sp<ABuffer> dequeueAccessUnitAC3();
sp<ABuffer> dequeueAccessUnitMPEGAudio();
sp<ABuffer> dequeueAccessUnitMPEGVideo();
sp<ABuffer> dequeueAccessUnitMPEG4Video();
diff --git a/media/libstagefright/rtsp/ARTSPConnection.cpp b/media/libstagefright/rtsp/ARTSPConnection.cpp
index 5116550..efde7a9 100644
--- a/media/libstagefright/rtsp/ARTSPConnection.cpp
+++ b/media/libstagefright/rtsp/ARTSPConnection.cpp
@@ -489,7 +489,6 @@ void ARTSPConnection::onReceiveResponse() {
FD_SET(mSocket, &rs);
int res = select(mSocket + 1, &rs, NULL, NULL, &tv);
- CHECK_GE(res, 0);
if (res == 1) {
MakeSocketBlocking(mSocket, true);
diff --git a/media/libstagefright/rtsp/MyHandler.h b/media/libstagefright/rtsp/MyHandler.h
index f4b5846..cd77aa0 100644
--- a/media/libstagefright/rtsp/MyHandler.h
+++ b/media/libstagefright/rtsp/MyHandler.h
@@ -686,23 +686,27 @@ struct MyHandler : public AHandler {
i = response->mHeaders.indexOfKey("transport");
CHECK_GE(i, 0);
- if (!track->mUsingInterleavedTCP) {
- AString transport = response->mHeaders.valueAt(i);
-
- // We are going to continue even if we were
- // unable to poke a hole into the firewall...
- pokeAHole(
- track->mRTPSocket,
- track->mRTCPSocket,
- transport);
- }
+ if (track->mRTPSocket != -1 && track->mRTCPSocket != -1) {
+ if (!track->mUsingInterleavedTCP) {
+ AString transport = response->mHeaders.valueAt(i);
+
+ // We are going to continue even if we were
+ // unable to poke a hole into the firewall...
+ pokeAHole(
+ track->mRTPSocket,
+ track->mRTCPSocket,
+ transport);
+ }
- mRTPConn->addStream(
- track->mRTPSocket, track->mRTCPSocket,
- mSessionDesc, index,
- notify, track->mUsingInterleavedTCP);
+ mRTPConn->addStream(
+ track->mRTPSocket, track->mRTCPSocket,
+ mSessionDesc, index,
+ notify, track->mUsingInterleavedTCP);
- mSetupTracksSuccessful = true;
+ mSetupTracksSuccessful = true;
+ } else {
+ result = BAD_VALUE;
+ }
}
}
@@ -726,7 +730,7 @@ struct MyHandler : public AHandler {
}
++index;
- if (index < mSessionDesc->countTracks()) {
+ if (result == OK && index < mSessionDesc->countTracks()) {
setupTrack(index);
} else if (mSetupTracksSuccessful) {
++mKeepAliveGeneration;
@@ -1559,6 +1563,8 @@ private:
info->mUsingInterleavedTCP = false;
info->mFirstSeqNumInSegment = 0;
info->mNewSegment = true;
+ info->mRTPSocket = -1;
+ info->mRTCPSocket = -1;
info->mRTPAnchor = 0;
info->mNTPAnchorUs = -1;
info->mNormalPlayTimeRTP = 0;
diff --git a/media/mtp/MtpDataPacket.cpp b/media/mtp/MtpDataPacket.cpp
index 930f0b0..c4f87a0 100644
--- a/media/mtp/MtpDataPacket.cpp
+++ b/media/mtp/MtpDataPacket.cpp
@@ -331,7 +331,7 @@ void MtpDataPacket::putString(const char* s) {
void MtpDataPacket::putString(const uint16_t* string) {
int count = 0;
- for (int i = 0; i < 256; i++) {
+ for (int i = 0; i <= MTP_STRING_MAX_CHARACTER_NUMBER; i++) {
if (string[i])
count++;
else
diff --git a/media/mtp/MtpStringBuffer.cpp b/media/mtp/MtpStringBuffer.cpp
index fe8cf04..f3420a4 100644
--- a/media/mtp/MtpStringBuffer.cpp
+++ b/media/mtp/MtpStringBuffer.cpp
@@ -56,42 +56,47 @@ MtpStringBuffer::~MtpStringBuffer() {
}
void MtpStringBuffer::set(const char* src) {
- int length = strlen(src);
- if (length >= sizeof(mBuffer))
- length = sizeof(mBuffer) - 1;
- memcpy(mBuffer, src, length);
-
// count the characters
int count = 0;
char ch;
- while ((ch = *src++) != 0) {
+ char* dest = (char*)mBuffer;
+
+ while ((ch = *src++) != 0 && count < MTP_STRING_MAX_CHARACTER_NUMBER) {
if ((ch & 0x80) == 0) {
// single byte character
+ *dest++ = ch;
} else if ((ch & 0xE0) == 0xC0) {
// two byte character
- if (! *src++) {
+ char ch1 = *src++;
+ if (! ch1) {
// last character was truncated, so ignore last byte
- length--;
break;
}
+
+ *dest++ = ch;
+ *dest++ = ch1;
} else if ((ch & 0xF0) == 0xE0) {
// 3 byte char
- if (! *src++) {
+ char ch1 = *src++;
+ if (! ch1) {
// last character was truncated, so ignore last byte
- length--;
break;
}
- if (! *src++) {
- // last character was truncated, so ignore last two bytes
- length -= 2;
+ char ch2 = *src++;
+ if (! ch2) {
+ // last character was truncated, so ignore last byte
break;
}
+
+ *dest++ = ch;
+ *dest++ = ch1;
+ *dest++ = ch2;
}
count++;
}
- mByteCount = length + 1;
- mBuffer[length] = 0;
+ *dest++ = 0;
+ mByteCount = dest - (char*)mBuffer;
mCharCount = count;
}
@@ -100,7 +105,7 @@ void MtpStringBuffer::set(const uint16_t* src) {
uint16_t ch;
uint8_t* dest = mBuffer;
- while ((ch = *src++) != 0 && count < 255) {
+ while ((ch = *src++) != 0 && count < MTP_STRING_MAX_CHARACTER_NUMBER) {
if (ch >= 0x0800) {
*dest++ = (uint8_t)(0xE0 | (ch >> 12));
*dest++ = (uint8_t)(0x80 | ((ch >> 6) & 0x3F));
diff --git a/media/mtp/MtpStringBuffer.h b/media/mtp/MtpStringBuffer.h
index cbc8307..e5150df 100644
--- a/media/mtp/MtpStringBuffer.h
+++ b/media/mtp/MtpStringBuffer.h
@@ -19,6 +19,9 @@
#include <stdint.h>
+// Max Character number of a MTP String
+#define MTP_STRING_MAX_CHARACTER_NUMBER 255
+
namespace android {
class MtpDataPacket;
@@ -29,7 +32,7 @@ class MtpStringBuffer {
private:
// mBuffer contains string in UTF8 format
// maximum 3 bytes/character, with 1 extra for zero termination
- uint8_t mBuffer[255 * 3 + 1];
+ uint8_t mBuffer[MTP_STRING_MAX_CHARACTER_NUMBER * 3 + 1];
int mCharCount;
int mByteCount;