Loading include/media/stagefright/MetaData.h +2 −0 Original line number Diff line number Diff line Loading @@ -70,6 +70,8 @@ enum { kKeyThumbnailTime = 'thbT', // int64_t (usecs) kKeyTrackID = 'trID', kKeyIsDRM = 'idrm', // int32_t (bool) kKeyEncoderDelay = 'encd', // int32_t (frames) kKeyEncoderPadding = 'encp', // int32_t (frames) kKeyAlbum = 'albu', // cstring kKeyArtist = 'arti', // cstring Loading media/libstagefright/MP3Extractor.cpp +37 −2 Original line number Diff line number Diff line Loading @@ -311,10 +311,18 @@ MP3Extractor::MP3Extractor( mMeta->setInt32(kKeyBitRate, bitrate * 1000); mMeta->setInt32(kKeyChannelCount, num_channels); mSeeker = XINGSeeker::CreateFromSource(mDataSource, mFirstFramePos); sp<XINGSeeker> seeker = XINGSeeker::CreateFromSource(mDataSource, mFirstFramePos); if (mSeeker == NULL) { if (seeker == NULL) { mSeeker = VBRISeeker::CreateFromSource(mDataSource, post_id3_pos); } else { mSeeker = seeker; int encd = seeker->getEncoderDelay(); int encp = seeker->getEncoderPadding(); if (encd != 0 || encp != 0) { mMeta->setInt32(kKeyEncoderDelay, encd); mMeta->setInt32(kKeyEncoderPadding, encp); } } if (mSeeker != NULL) { Loading Loading @@ -547,6 +555,33 @@ sp<MetaData> MP3Extractor::getMetaData() { return meta; } ID3::Iterator *com = new ID3::Iterator(id3, "COM"); if (com->done()) { delete com; com = new ID3::Iterator(id3, "COMM"); } while(!com->done()) { String8 commentdesc; String8 commentvalue; com->getString(&commentdesc, &commentvalue); const char * desc = commentdesc.string(); const char * value = commentvalue.string(); // first 3 characters are the language, which we don't care about if(strlen(desc) > 3 && strcmp(desc + 3, "iTunSMPB") == 0) { int32_t delay, padding; if (sscanf(value, " %*x %x %x %*x", &delay, &padding) == 2) { mMeta->setInt32(kKeyEncoderDelay, delay); mMeta->setInt32(kKeyEncoderPadding, padding); } break; } com->next(); } delete com; com = NULL; struct Map { int key; const char *tag1; Loading media/libstagefright/XINGSeeker.cpp +29 −3 Original line number Diff line number Diff line Loading @@ -14,6 +14,9 @@ * limitations under the License. */ #define LOG_TAG "XINGSEEKER" #include <utils/Log.h> #include "include/XINGSeeker.h" #include "include/avc_utils.h" Loading @@ -24,7 +27,9 @@ namespace android { XINGSeeker::XINGSeeker() : mDurationUs(-1), mSizeBytes(0) { mSizeBytes(0), mEncoderDelay(0), mEncoderPadding(0) { } bool XINGSeeker::getDuration(int64_t *durationUs) { Loading Loading @@ -76,8 +81,6 @@ sp<XINGSeeker> XINGSeeker::CreateFromSource( seeker->mFirstFramePos = first_frame_pos; ALOGI("xingseeker first frame pos: %lld", first_frame_pos); seeker->mSizeBytes = 0; seeker->mTOCValid = false; seeker->mDurationUs = 0; Loading Loading @@ -111,6 +114,8 @@ sp<XINGSeeker> XINGSeeker::CreateFromSource( else offset += 9; } int xingbase = offset; if (source->readAt(offset, &buffer, 4) < 4) { // XING header ID return NULL; } Loading Loading @@ -161,10 +166,31 @@ sp<XINGSeeker> XINGSeeker::CreateFromSource( // do something with the quality indicator offset += 4; } if (source->readAt(xingbase + 0xaf - 0x24, &buffer, 1) < 1) { // encoding flags return false; } ALOGV("nogap preceding: %s, nogap continued in next: %s", (buffer[0] & 0x80) ? "true" : "false", (buffer[0] & 0x40) ? "true" : "false"); #endif if (source->readAt(xingbase + 0xb1 - 0x24, &buffer, 3) == 3) { seeker->mEncoderDelay = (buffer[0] << 4) + (buffer[1] >> 4); seeker->mEncoderPadding = ((buffer[1] & 0xf) << 8) + buffer[2]; } return seeker; } int32_t XINGSeeker::getEncoderDelay() { return mEncoderDelay; } int32_t XINGSeeker::getEncoderPadding() { return mEncoderPadding; } } // namespace android media/libstagefright/id3/ID3.cpp +36 −11 Original line number Diff line number Diff line Loading @@ -463,40 +463,65 @@ static void convertISO8859ToString8( tmp = NULL; } void ID3::Iterator::getString(String8 *id) const { // the 2nd argument is used to get the data following the \0 in a comment field void ID3::Iterator::getString(String8 *id, String8 *comment) const { getstring(id, false); if (comment != NULL) { getstring(comment, true); } } // comment fields (COM/COMM) contain an initial short descriptor, followed by \0, // followed by more data. The data following the \0 can be retrieved by setting // "otherdata" to true. void ID3::Iterator::getstring(String8 *id, bool otherdata) const { id->setTo(""); if (mFrameData == NULL) { const uint8_t *frameData = mFrameData; if (frameData == NULL) { return; } uint8_t encoding = *frameData; if (mParent.mVersion == ID3_V1 || mParent.mVersion == ID3_V1_1) { if (mOffset == 126 || mOffset == 127) { // Special treatment for the track number and genre. char tmp[16]; sprintf(tmp, "%d", (int)*mFrameData); sprintf(tmp, "%d", (int)*frameData); id->setTo(tmp); return; } convertISO8859ToString8(mFrameData, mFrameSize, id); convertISO8859ToString8(frameData, mFrameSize, id); return; } size_t n = mFrameSize - getHeaderLength() - 1; if (otherdata) { // skip past the encoding, language, and the 0 separator frameData += 4; int32_t i = n - 4; while(--i >= 0 && *++frameData != 0) ; int skipped = (frameData - mFrameData); if (skipped >= n) { return; } n -= skipped; } if (*mFrameData == 0x00) { if (encoding == 0x00) { // ISO 8859-1 convertISO8859ToString8(mFrameData + 1, n, id); } else if (*mFrameData == 0x03) { convertISO8859ToString8(frameData + 1, n, id); } else if (encoding == 0x03) { // UTF-8 id->setTo((const char *)(mFrameData + 1), n); } else if (*mFrameData == 0x02) { id->setTo((const char *)(frameData + 1), n); } else if (encoding == 0x02) { // UTF-16 BE, no byte order mark. // API wants number of characters, not number of bytes... int len = n / 2; const char16_t *framedata = (const char16_t *) (mFrameData + 1); const char16_t *framedata = (const char16_t *) (frameData + 1); char16_t *framedatacopy = NULL; #if BYTE_ORDER == LITTLE_ENDIAN framedatacopy = new char16_t[len]; Loading @@ -513,7 +538,7 @@ void ID3::Iterator::getString(String8 *id) const { // UCS-2 // API wants number of characters, not number of bytes... int len = n / 2; const char16_t *framedata = (const char16_t *) (mFrameData + 1); const char16_t *framedata = (const char16_t *) (frameData + 1); char16_t *framedatacopy = NULL; if (*framedata == 0xfffe) { // endianness marker doesn't match host endianness, convert Loading media/libstagefright/include/ID3.h +2 −1 Original line number Diff line number Diff line Loading @@ -50,7 +50,7 @@ struct ID3 { bool done() const; void getID(String8 *id) const; void getString(String8 *s) const; void getString(String8 *s, String8 *ss = NULL) const; const uint8_t *getData(size_t *length) const; void next(); Loading @@ -65,6 +65,7 @@ struct ID3 { void findFrame(); size_t getHeaderLength() const; void getstring(String8 *s, bool secondhalf) const; Iterator(const Iterator &); Iterator &operator=(const Iterator &); Loading Loading
include/media/stagefright/MetaData.h +2 −0 Original line number Diff line number Diff line Loading @@ -70,6 +70,8 @@ enum { kKeyThumbnailTime = 'thbT', // int64_t (usecs) kKeyTrackID = 'trID', kKeyIsDRM = 'idrm', // int32_t (bool) kKeyEncoderDelay = 'encd', // int32_t (frames) kKeyEncoderPadding = 'encp', // int32_t (frames) kKeyAlbum = 'albu', // cstring kKeyArtist = 'arti', // cstring Loading
media/libstagefright/MP3Extractor.cpp +37 −2 Original line number Diff line number Diff line Loading @@ -311,10 +311,18 @@ MP3Extractor::MP3Extractor( mMeta->setInt32(kKeyBitRate, bitrate * 1000); mMeta->setInt32(kKeyChannelCount, num_channels); mSeeker = XINGSeeker::CreateFromSource(mDataSource, mFirstFramePos); sp<XINGSeeker> seeker = XINGSeeker::CreateFromSource(mDataSource, mFirstFramePos); if (mSeeker == NULL) { if (seeker == NULL) { mSeeker = VBRISeeker::CreateFromSource(mDataSource, post_id3_pos); } else { mSeeker = seeker; int encd = seeker->getEncoderDelay(); int encp = seeker->getEncoderPadding(); if (encd != 0 || encp != 0) { mMeta->setInt32(kKeyEncoderDelay, encd); mMeta->setInt32(kKeyEncoderPadding, encp); } } if (mSeeker != NULL) { Loading Loading @@ -547,6 +555,33 @@ sp<MetaData> MP3Extractor::getMetaData() { return meta; } ID3::Iterator *com = new ID3::Iterator(id3, "COM"); if (com->done()) { delete com; com = new ID3::Iterator(id3, "COMM"); } while(!com->done()) { String8 commentdesc; String8 commentvalue; com->getString(&commentdesc, &commentvalue); const char * desc = commentdesc.string(); const char * value = commentvalue.string(); // first 3 characters are the language, which we don't care about if(strlen(desc) > 3 && strcmp(desc + 3, "iTunSMPB") == 0) { int32_t delay, padding; if (sscanf(value, " %*x %x %x %*x", &delay, &padding) == 2) { mMeta->setInt32(kKeyEncoderDelay, delay); mMeta->setInt32(kKeyEncoderPadding, padding); } break; } com->next(); } delete com; com = NULL; struct Map { int key; const char *tag1; Loading
media/libstagefright/XINGSeeker.cpp +29 −3 Original line number Diff line number Diff line Loading @@ -14,6 +14,9 @@ * limitations under the License. */ #define LOG_TAG "XINGSEEKER" #include <utils/Log.h> #include "include/XINGSeeker.h" #include "include/avc_utils.h" Loading @@ -24,7 +27,9 @@ namespace android { XINGSeeker::XINGSeeker() : mDurationUs(-1), mSizeBytes(0) { mSizeBytes(0), mEncoderDelay(0), mEncoderPadding(0) { } bool XINGSeeker::getDuration(int64_t *durationUs) { Loading Loading @@ -76,8 +81,6 @@ sp<XINGSeeker> XINGSeeker::CreateFromSource( seeker->mFirstFramePos = first_frame_pos; ALOGI("xingseeker first frame pos: %lld", first_frame_pos); seeker->mSizeBytes = 0; seeker->mTOCValid = false; seeker->mDurationUs = 0; Loading Loading @@ -111,6 +114,8 @@ sp<XINGSeeker> XINGSeeker::CreateFromSource( else offset += 9; } int xingbase = offset; if (source->readAt(offset, &buffer, 4) < 4) { // XING header ID return NULL; } Loading Loading @@ -161,10 +166,31 @@ sp<XINGSeeker> XINGSeeker::CreateFromSource( // do something with the quality indicator offset += 4; } if (source->readAt(xingbase + 0xaf - 0x24, &buffer, 1) < 1) { // encoding flags return false; } ALOGV("nogap preceding: %s, nogap continued in next: %s", (buffer[0] & 0x80) ? "true" : "false", (buffer[0] & 0x40) ? "true" : "false"); #endif if (source->readAt(xingbase + 0xb1 - 0x24, &buffer, 3) == 3) { seeker->mEncoderDelay = (buffer[0] << 4) + (buffer[1] >> 4); seeker->mEncoderPadding = ((buffer[1] & 0xf) << 8) + buffer[2]; } return seeker; } int32_t XINGSeeker::getEncoderDelay() { return mEncoderDelay; } int32_t XINGSeeker::getEncoderPadding() { return mEncoderPadding; } } // namespace android
media/libstagefright/id3/ID3.cpp +36 −11 Original line number Diff line number Diff line Loading @@ -463,40 +463,65 @@ static void convertISO8859ToString8( tmp = NULL; } void ID3::Iterator::getString(String8 *id) const { // the 2nd argument is used to get the data following the \0 in a comment field void ID3::Iterator::getString(String8 *id, String8 *comment) const { getstring(id, false); if (comment != NULL) { getstring(comment, true); } } // comment fields (COM/COMM) contain an initial short descriptor, followed by \0, // followed by more data. The data following the \0 can be retrieved by setting // "otherdata" to true. void ID3::Iterator::getstring(String8 *id, bool otherdata) const { id->setTo(""); if (mFrameData == NULL) { const uint8_t *frameData = mFrameData; if (frameData == NULL) { return; } uint8_t encoding = *frameData; if (mParent.mVersion == ID3_V1 || mParent.mVersion == ID3_V1_1) { if (mOffset == 126 || mOffset == 127) { // Special treatment for the track number and genre. char tmp[16]; sprintf(tmp, "%d", (int)*mFrameData); sprintf(tmp, "%d", (int)*frameData); id->setTo(tmp); return; } convertISO8859ToString8(mFrameData, mFrameSize, id); convertISO8859ToString8(frameData, mFrameSize, id); return; } size_t n = mFrameSize - getHeaderLength() - 1; if (otherdata) { // skip past the encoding, language, and the 0 separator frameData += 4; int32_t i = n - 4; while(--i >= 0 && *++frameData != 0) ; int skipped = (frameData - mFrameData); if (skipped >= n) { return; } n -= skipped; } if (*mFrameData == 0x00) { if (encoding == 0x00) { // ISO 8859-1 convertISO8859ToString8(mFrameData + 1, n, id); } else if (*mFrameData == 0x03) { convertISO8859ToString8(frameData + 1, n, id); } else if (encoding == 0x03) { // UTF-8 id->setTo((const char *)(mFrameData + 1), n); } else if (*mFrameData == 0x02) { id->setTo((const char *)(frameData + 1), n); } else if (encoding == 0x02) { // UTF-16 BE, no byte order mark. // API wants number of characters, not number of bytes... int len = n / 2; const char16_t *framedata = (const char16_t *) (mFrameData + 1); const char16_t *framedata = (const char16_t *) (frameData + 1); char16_t *framedatacopy = NULL; #if BYTE_ORDER == LITTLE_ENDIAN framedatacopy = new char16_t[len]; Loading @@ -513,7 +538,7 @@ void ID3::Iterator::getString(String8 *id) const { // UCS-2 // API wants number of characters, not number of bytes... int len = n / 2; const char16_t *framedata = (const char16_t *) (mFrameData + 1); const char16_t *framedata = (const char16_t *) (frameData + 1); char16_t *framedatacopy = NULL; if (*framedata == 0xfffe) { // endianness marker doesn't match host endianness, convert Loading
media/libstagefright/include/ID3.h +2 −1 Original line number Diff line number Diff line Loading @@ -50,7 +50,7 @@ struct ID3 { bool done() const; void getID(String8 *id) const; void getString(String8 *s) const; void getString(String8 *s, String8 *ss = NULL) const; const uint8_t *getData(size_t *length) const; void next(); Loading @@ -65,6 +65,7 @@ struct ID3 { void findFrame(); size_t getHeaderLength() const; void getstring(String8 *s, bool secondhalf) const; Iterator(const Iterator &); Iterator &operator=(const Iterator &); Loading