summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
Diffstat (limited to 'media')
-rw-r--r--media/libmedia/AudioParameter.cpp5
-rw-r--r--media/libstagefright/MPEG4Extractor.cpp131
-rw-r--r--media/libstagefright/MediaCodec.cpp6
-rw-r--r--media/libstagefright/include/MPEG4Extractor.h3
-rw-r--r--media/libstagefright/rtsp/ARTSPConnection.cpp1
-rw-r--r--media/libstagefright/rtsp/MyHandler.h38
6 files changed, 162 insertions, 22 deletions
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/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index ad985ee..cbc169b 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -38,6 +38,8 @@
#include <media/stagefright/MetaData.h>
#include <utils/String8.h>
+#include <byteswap.h>
+
namespace android {
class MPEG4Source : public MediaSource {
@@ -1615,7 +1617,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;
@@ -1747,6 +1749,23 @@ 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('-', '-', '-', '-'):
{
mLastCommentMean.clear();
@@ -1981,7 +2000,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) {
return ERROR_MALFORMED;
}
@@ -2168,6 +2187,114 @@ 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;
+}
+
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 e0686be..e299caf 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/include/MPEG4Extractor.h b/media/libstagefright/include/MPEG4Extractor.h
index bbec1c4..bd5e4b9 100644
--- a/media/libstagefright/include/MPEG4Extractor.h
+++ b/media/libstagefright/include/MPEG4Extractor.h
@@ -95,7 +95,8 @@ 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);
status_t updateAudioTrackInfoFromESDS_MPEG4Audio(
const void *esds_data, size_t esds_size);
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;