summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/Utils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'media/libstagefright/Utils.cpp')
-rw-r--r--media/libstagefright/Utils.cpp203
1 files changed, 194 insertions, 9 deletions
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index 216a329..25afc5b 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -17,11 +17,13 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "Utils"
#include <utils/Log.h>
+#include <ctype.h>
#include "include/ESDS.h"
#include <arpa/inet.h>
#include <cutils/properties.h>
+#include <media/openmax/OMX_Audio.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
@@ -83,6 +85,11 @@ status_t convertMetaDataToMessage(
msg->setInt64("durationUs", durationUs);
}
+ int avgBitRate;
+ if (meta->findInt32(kKeyBitRate, &avgBitRate)) {
+ msg->setInt32("bit-rate", avgBitRate);
+ }
+
int32_t isSync;
if (meta->findInt32(kKeyIsSyncFrame, &isSync) && isSync != 0) {
msg->setInt32("is-sync-frame", 1);
@@ -102,6 +109,25 @@ status_t convertMetaDataToMessage(
msg->setInt32("sar-width", sarWidth);
msg->setInt32("sar-height", sarHeight);
}
+
+ int32_t colorFormat;
+ if (meta->findInt32(kKeyColorFormat, &colorFormat)) {
+ msg->setInt32("color-format", colorFormat);
+ }
+
+ int32_t cropLeft, cropTop, cropRight, cropBottom;
+ if (meta->findRect(kKeyCropRect,
+ &cropLeft,
+ &cropTop,
+ &cropRight,
+ &cropBottom)) {
+ msg->setRect("crop", cropLeft, cropTop, cropRight, cropBottom);
+ }
+
+ int32_t rotationDegrees;
+ if (meta->findInt32(kKeyRotation, &rotationDegrees)) {
+ msg->setInt32("rotation-degrees", rotationDegrees);
+ }
} else if (!strncasecmp("audio/", mime, 6)) {
int32_t numChannels, sampleRate;
CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
@@ -128,6 +154,11 @@ status_t convertMetaDataToMessage(
if (meta->findInt32(kKeyIsADTS, &isADTS)) {
msg->setInt32("is-adts", true);
}
+
+ int32_t aacProfile = -1;
+ if (meta->findInt32(kKeyAACAOT, &aacProfile)) {
+ msg->setInt32("aac-profile", aacProfile);
+ }
}
int32_t maxInputSize;
@@ -135,6 +166,11 @@ status_t convertMetaDataToMessage(
msg->setInt32("max-input-size", maxInputSize);
}
+ int32_t rotationDegrees;
+ if (meta->findInt32(kKeyRotation, &rotationDegrees)) {
+ msg->setInt32("rotation-degrees", rotationDegrees);
+ }
+
uint32_t type;
const void *data;
size_t size;
@@ -216,6 +252,56 @@ status_t convertMetaDataToMessage(
buffer->meta()->setInt32("csd", true);
buffer->meta()->setInt64("timeUs", 0);
msg->setBuffer("csd-1", buffer);
+ } else if (meta->findData(kKeyHVCC, &type, &data, &size)) {
+ const uint8_t *ptr = (const uint8_t *)data;
+
+ CHECK(size >= 7);
+ CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1
+ uint8_t profile = ptr[1] & 31;
+ uint8_t level = ptr[12];
+ ptr += 22;
+ size -= 22;
+
+
+ size_t numofArrays = (char)ptr[0];
+ ptr += 1;
+ size -= 1;
+ size_t j = 0, i = 0;
+
+ sp<ABuffer> buffer = new ABuffer(1024);
+ buffer->setRange(0, 0);
+
+ for (i = 0; i < numofArrays; i++) {
+ ptr += 1;
+ size -= 1;
+
+ //Num of nals
+ size_t numofNals = U16_AT(ptr);
+
+ ptr += 2;
+ size -= 2;
+
+ for (j = 0; j < numofNals; j++) {
+ CHECK(size >= 2);
+ size_t length = U16_AT(ptr);
+
+ ptr += 2;
+ size -= 2;
+
+ CHECK(size >= length);
+
+ memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4);
+ memcpy(buffer->data() + buffer->size() + 4, ptr, length);
+ buffer->setRange(0, buffer->size() + 4 + length);
+
+ ptr += length;
+ size -= length;
+ }
+ }
+ buffer->meta()->setInt32("csd", true);
+ buffer->meta()->setInt64("timeUs", 0);
+ msg->setBuffer("csd-0", buffer);
+
} else if (meta->findData(kKeyESDS, &type, &data, &size)) {
ESDS esds((const char *)data, size);
CHECK_EQ(esds.InitCheck(), (status_t)OK);
@@ -251,6 +337,13 @@ status_t convertMetaDataToMessage(
buffer->meta()->setInt32("csd", true);
buffer->meta()->setInt64("timeUs", 0);
msg->setBuffer("csd-1", buffer);
+ } else if (meta->findData(kKeyOpusHeader, &type, &data, &size)) {
+ sp<ABuffer> buffer = new ABuffer(size);
+ memcpy(buffer->data(), data, size);
+
+ buffer->meta()->setInt32("csd", true);
+ buffer->meta()->setInt64("timeUs", 0);
+ msg->setBuffer("csd-0", buffer);
}
*format = msg;
@@ -277,7 +370,7 @@ static size_t reassembleAVCC(const sp<ABuffer> &csd0, const sp<ABuffer> csd1, ch
// there can't be another param here, so use all the rest
i = csd0->size();
}
- ALOGV("block at %d, last was %d", i, lastparamoffset);
+ ALOGV("block at %zu, last was %d", i, lastparamoffset);
if (lastparamoffset > 0) {
int size = i - lastparamoffset;
avcc[avccidx++] = size >> 8;
@@ -308,7 +401,7 @@ static size_t reassembleAVCC(const sp<ABuffer> &csd0, const sp<ABuffer> csd1, ch
// there can't be another param here, so use all the rest
i = csd1->size();
}
- ALOGV("block at %d, last was %d", i, lastparamoffset);
+ ALOGV("block at %zu, last was %d", i, lastparamoffset);
if (lastparamoffset > 0) {
int size = i - lastparamoffset;
avcc[avccidx++] = size >> 8;
@@ -401,6 +494,25 @@ void convertMessageToMetaData(const sp<AMessage> &msg, sp<MetaData> &meta) {
meta->setInt32(kKeySARWidth, sarWidth);
meta->setInt32(kKeySARHeight, sarHeight);
}
+
+ int32_t colorFormat;
+ if (msg->findInt32("color-format", &colorFormat)) {
+ meta->setInt32(kKeyColorFormat, colorFormat);
+ }
+
+ int32_t cropLeft, cropTop, cropRight, cropBottom;
+ if (msg->findRect("crop",
+ &cropLeft,
+ &cropTop,
+ &cropRight,
+ &cropBottom)) {
+ meta->setRect(kKeyCropRect, cropLeft, cropTop, cropRight, cropBottom);
+ }
+
+ int32_t rotationDegrees;
+ if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
+ meta->setInt32(kKeyRotation, rotationDegrees);
+ }
} else if (mime.startsWith("audio/")) {
int32_t numChannels;
if (msg->findInt32("channel-count", &numChannels)) {
@@ -452,6 +564,11 @@ void convertMessageToMetaData(const sp<AMessage> &msg, sp<MetaData> &meta) {
}
}
+ int32_t timeScale;
+ if (msg->findInt32("time-scale", &timeScale)) {
+ meta->setInt32(kKeyTimeScale, timeScale);
+ }
+
// XXX TODO add whatever other keys there are
#if 0
@@ -523,6 +640,7 @@ static const struct mime_conv_t mimeLookup[] = {
{ MEDIA_MIMETYPE_AUDIO_AMR_WB, AUDIO_FORMAT_AMR_WB },
{ MEDIA_MIMETYPE_AUDIO_AAC, AUDIO_FORMAT_AAC },
{ MEDIA_MIMETYPE_AUDIO_VORBIS, AUDIO_FORMAT_VORBIS },
+ { MEDIA_MIMETYPE_AUDIO_OPUS, AUDIO_FORMAT_OPUS},
{ 0, AUDIO_FORMAT_INVALID }
};
@@ -540,10 +658,46 @@ const struct mime_conv_t* p = &mimeLookup[0];
return BAD_VALUE;
}
+struct aac_format_conv_t {
+ OMX_AUDIO_AACPROFILETYPE eAacProfileType;
+ audio_format_t format;
+};
+
+static const struct aac_format_conv_t profileLookup[] = {
+ { OMX_AUDIO_AACObjectMain, AUDIO_FORMAT_AAC_MAIN},
+ { OMX_AUDIO_AACObjectLC, AUDIO_FORMAT_AAC_LC},
+ { OMX_AUDIO_AACObjectSSR, AUDIO_FORMAT_AAC_SSR},
+ { OMX_AUDIO_AACObjectLTP, AUDIO_FORMAT_AAC_LTP},
+ { OMX_AUDIO_AACObjectHE, AUDIO_FORMAT_AAC_HE_V1},
+ { OMX_AUDIO_AACObjectScalable, AUDIO_FORMAT_AAC_SCALABLE},
+ { OMX_AUDIO_AACObjectERLC, AUDIO_FORMAT_AAC_ERLC},
+ { OMX_AUDIO_AACObjectLD, AUDIO_FORMAT_AAC_LD},
+ { OMX_AUDIO_AACObjectHE_PS, AUDIO_FORMAT_AAC_HE_V2},
+ { OMX_AUDIO_AACObjectELD, AUDIO_FORMAT_AAC_ELD},
+ { OMX_AUDIO_AACObjectNull, AUDIO_FORMAT_AAC},
+};
+
+void mapAACProfileToAudioFormat( audio_format_t& format, uint64_t eAacProfile)
+{
+const struct aac_format_conv_t* p = &profileLookup[0];
+ while (p->eAacProfileType != OMX_AUDIO_AACObjectNull) {
+ if (eAacProfile == p->eAacProfileType) {
+ format = p->format;
+ return;
+ }
+ ++p;
+ }
+ format = AUDIO_FORMAT_AAC;
+ return;
+}
+
bool canOffloadStream(const sp<MetaData>& meta, bool hasVideo,
bool isStreaming, audio_stream_type_t streamType)
{
const char *mime;
+ if (meta == NULL) {
+ return false;
+ }
CHECK(meta->findCString(kKeyMIMEType, &mime));
audio_offload_info_t info = AUDIO_INFO_INITIALIZER;
@@ -562,15 +716,11 @@ bool canOffloadStream(const sp<MetaData>& meta, bool hasVideo,
return false;
}
- // check whether it is ELD/LD content -> no offloading
- // FIXME: this should depend on audio DSP capabilities. mapMimeToAudioFormat() should use the
- // metadata to refine the AAC format and the audio HAL should only list supported profiles.
+ // Redefine aac format according to its profile
+ // Offloading depends on audio DSP capabilities.
int32_t aacaot = -1;
if (meta->findInt32(kKeyAACAOT, &aacaot)) {
- if (aacaot == 23 || aacaot == 39 ) {
- ALOGV("track of type '%s' is ELD/LD content", mime);
- return false;
- }
+ mapAACProfileToAudioFormat(info.format,(OMX_AUDIO_AACPROFILETYPE) aacaot);
}
int32_t srate = -1;
@@ -615,5 +765,40 @@ bool canOffloadStream(const sp<MetaData>& meta, bool hasVideo,
return AudioSystem::isOffloadSupported(info);
}
+AString uriDebugString(const AString &uri, bool incognito) {
+ if (incognito) {
+ return AString("<URI suppressed>");
+ }
+
+ char prop[PROPERTY_VALUE_MAX];
+ if (property_get("media.stagefright.log-uri", prop, "false") &&
+ (!strcmp(prop, "1") || !strcmp(prop, "true"))) {
+ return uri;
+ }
+
+ // find scheme
+ AString scheme;
+ const char *chars = uri.c_str();
+ for (size_t i = 0; i < uri.size(); i++) {
+ const char c = chars[i];
+ if (!isascii(c)) {
+ break;
+ } else if (isalpha(c)) {
+ continue;
+ } else if (i == 0) {
+ // first character must be a letter
+ break;
+ } else if (isdigit(c) || c == '+' || c == '.' || c =='-') {
+ continue;
+ } else if (c != ':') {
+ break;
+ }
+ scheme = AString(uri, 0, i);
+ scheme.append("://<suppressed>");
+ return scheme;
+ }
+ return AString("<no-scheme URI suppressed>");
+}
+
} // namespace android