Loading media/libstagefright/rtsp/AMPEG4ElementaryAssembler.cpp +242 −3 Original line number Original line Diff line number Diff line Loading @@ -18,29 +18,160 @@ #include "ARTPSource.h" #include "ARTPSource.h" #include <media/stagefright/foundation/ABitReader.h> #include <media/stagefright/foundation/ABuffer.h> #include <media/stagefright/foundation/ABuffer.h> #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/AMessage.h> #include <media/stagefright/foundation/AMessage.h> #include <media/stagefright/foundation/hexdump.h> #include <media/stagefright/foundation/hexdump.h> #include <media/stagefright/Utils.h> #include <ctype.h> #include <stdint.h> #include <stdint.h> #define BE_VERBOSE 0 #define BE_VERBOSE 0 namespace android { namespace android { static bool GetAttribute(const char *s, const char *key, AString *value) { value->clear(); size_t keyLen = strlen(key); for (;;) { while (isspace(*s)) { ++s; } const char *colonPos = strchr(s, ';'); size_t len = (colonPos == NULL) ? strlen(s) : colonPos - s; if (len >= keyLen + 1 && s[keyLen] == '=' && !strncasecmp(s, key, keyLen)) { value->setTo(&s[keyLen + 1], len - keyLen - 1); return true; } if (colonPos == NULL) { return false; } s = colonPos + 1; } } static bool GetIntegerAttribute( const char *s, const char *key, unsigned *x) { *x = 0; AString val; if (!GetAttribute(s, key, &val)) { return false; } s = val.c_str(); char *end; unsigned y = strtoul(s, &end, 10); if (end == s || *end != '\0') { return false; } *x = y; return true; } // static // static AMPEG4ElementaryAssembler::AMPEG4ElementaryAssembler(const sp<AMessage> ¬ify) AMPEG4ElementaryAssembler::AMPEG4ElementaryAssembler( const sp<AMessage> ¬ify, const AString &desc, const AString ¶ms) : mNotifyMsg(notify), : mNotifyMsg(notify), mIsGeneric(false), mParams(params), mSizeLength(0), mIndexLength(0), mIndexDeltaLength(0), mCTSDeltaLength(0), mDTSDeltaLength(0), mRandomAccessIndication(false), mStreamStateIndication(0), mAuxiliaryDataSizeLength(0), mHasAUHeader(false), mAccessUnitRTPTime(0), mAccessUnitRTPTime(0), mNextExpectedSeqNoValid(false), mNextExpectedSeqNoValid(false), mNextExpectedSeqNo(0), mNextExpectedSeqNo(0), mAccessUnitDamaged(false) { mAccessUnitDamaged(false) { mIsGeneric = desc.startsWith("mpeg4-generic/"); if (mIsGeneric) { AString value; CHECK(GetAttribute(params.c_str(), "mode", &value)); if (!GetIntegerAttribute(params.c_str(), "sizeLength", &mSizeLength)) { mSizeLength = 0; } if (!GetIntegerAttribute( params.c_str(), "indexLength", &mIndexLength)) { mIndexLength = 0; } if (!GetIntegerAttribute( params.c_str(), "indexDeltaLength", &mIndexDeltaLength)) { mIndexDeltaLength = 0; } if (!GetIntegerAttribute( params.c_str(), "CTSDeltaLength", &mCTSDeltaLength)) { mCTSDeltaLength = 0; } if (!GetIntegerAttribute( params.c_str(), "DTSDeltaLength", &mDTSDeltaLength)) { mDTSDeltaLength = 0; } unsigned x; if (!GetIntegerAttribute( params.c_str(), "randomAccessIndication", &x)) { mRandomAccessIndication = false; } else { CHECK(x == 0 || x == 1); mRandomAccessIndication = (x != 0); } if (!GetIntegerAttribute( params.c_str(), "streamStateIndication", &mStreamStateIndication)) { mStreamStateIndication = 0; } if (!GetIntegerAttribute( params.c_str(), "auxiliaryDataSizeLength", &mAuxiliaryDataSizeLength)) { mAuxiliaryDataSizeLength = 0; } mHasAUHeader = mSizeLength > 0 || mIndexLength > 0 || mIndexDeltaLength > 0 || mCTSDeltaLength > 0 || mDTSDeltaLength > 0 || mRandomAccessIndication || mStreamStateIndication > 0; } } } AMPEG4ElementaryAssembler::~AMPEG4ElementaryAssembler() { AMPEG4ElementaryAssembler::~AMPEG4ElementaryAssembler() { } } struct AUHeader { unsigned mSize; unsigned mSerial; }; ARTPAssembler::AssemblyStatus AMPEG4ElementaryAssembler::addPacket( ARTPAssembler::AssemblyStatus AMPEG4ElementaryAssembler::addPacket( const sp<ARTPSource> &source) { const sp<ARTPSource> &source) { List<sp<ABuffer> > *queue = source->queue(); List<sp<ABuffer> > *queue = source->queue(); Loading Loading @@ -85,9 +216,117 @@ ARTPAssembler::AssemblyStatus AMPEG4ElementaryAssembler::addPacket( } } mAccessUnitRTPTime = rtpTime; mAccessUnitRTPTime = rtpTime; if (!mIsGeneric) { mPackets.push_back(buffer); mPackets.push_back(buffer); } else { // hexdump(buffer->data(), buffer->size()); // hexdump(buffer->data(), buffer->size()); CHECK_GE(buffer->size(), 2u); unsigned AU_headers_length = U16_AT(buffer->data()); // in bits CHECK_GE(buffer->size(), 2 + (AU_headers_length + 7) / 8); List<AUHeader> headers; ABitReader bits(buffer->data() + 2, buffer->size() - 2); unsigned numBitsLeft = AU_headers_length; unsigned AU_serial = 0; for (;;) { if (numBitsLeft < mSizeLength) { break; } unsigned AU_size = bits.getBits(mSizeLength); numBitsLeft -= mSizeLength; size_t n = headers.empty() ? mIndexLength : mIndexDeltaLength; if (numBitsLeft < n) { break; } unsigned AU_index = bits.getBits(n); numBitsLeft -= n; if (headers.empty()) { AU_serial = AU_index; } else { AU_serial += 1 + AU_index; } if (mCTSDeltaLength > 0) { if (numBitsLeft < 1) { break; } --numBitsLeft; if (bits.getBits(1)) { if (numBitsLeft < mCTSDeltaLength) { break; } bits.skipBits(mCTSDeltaLength); numBitsLeft -= mCTSDeltaLength; } } if (mDTSDeltaLength > 0) { if (numBitsLeft < 1) { break; } --numBitsLeft; if (bits.getBits(1)) { if (numBitsLeft < mDTSDeltaLength) { break; } bits.skipBits(mDTSDeltaLength); numBitsLeft -= mDTSDeltaLength; } } if (mRandomAccessIndication) { if (numBitsLeft < 1) { break; } bits.skipBits(1); --numBitsLeft; } if (mStreamStateIndication > 0) { if (numBitsLeft < mStreamStateIndication) { break; } bits.skipBits(mStreamStateIndication); } AUHeader header; header.mSize = AU_size; header.mSerial = AU_serial; headers.push_back(header); } size_t offset = 2 + (AU_headers_length + 7) / 8; if (mAuxiliaryDataSizeLength > 0) { ABitReader bits(buffer->data() + offset, buffer->size() - offset); unsigned auxSize = bits.getBits(mAuxiliaryDataSizeLength); offset += (mAuxiliaryDataSizeLength + auxSize + 7) / 8; } for (List<AUHeader>::iterator it = headers.begin(); it != headers.end(); ++it) { const AUHeader &header = *it; CHECK_LE(offset + header.mSize, buffer->size()); sp<ABuffer> accessUnit = new ABuffer(header.mSize); memcpy(accessUnit->data(), buffer->data() + offset, header.mSize); offset += header.mSize; CopyTimes(accessUnit, buffer); mPackets.push_back(accessUnit); } CHECK_EQ(offset, buffer->size()); } queue->erase(queue->begin()); queue->erase(queue->begin()); ++mNextExpectedSeqNo; ++mNextExpectedSeqNo; Loading media/libstagefright/rtsp/AMPEG4ElementaryAssembler.h +17 −1 Original line number Original line Diff line number Diff line Loading @@ -20,6 +20,8 @@ #include "ARTPAssembler.h" #include "ARTPAssembler.h" #include <media/stagefright/foundation/AString.h> #include <utils/List.h> #include <utils/List.h> #include <utils/RefBase.h> #include <utils/RefBase.h> Loading @@ -29,7 +31,9 @@ struct ABuffer; struct AMessage; struct AMessage; struct AMPEG4ElementaryAssembler : public ARTPAssembler { struct AMPEG4ElementaryAssembler : public ARTPAssembler { AMPEG4ElementaryAssembler(const sp<AMessage> ¬ify); AMPEG4ElementaryAssembler( const sp<AMessage> ¬ify, const AString &desc, const AString ¶ms); protected: protected: virtual ~AMPEG4ElementaryAssembler(); virtual ~AMPEG4ElementaryAssembler(); Loading @@ -40,6 +44,18 @@ protected: private: private: sp<AMessage> mNotifyMsg; sp<AMessage> mNotifyMsg; bool mIsGeneric; AString mParams; unsigned mSizeLength; unsigned mIndexLength; unsigned mIndexDeltaLength; unsigned mCTSDeltaLength; unsigned mDTSDeltaLength; bool mRandomAccessIndication; unsigned mStreamStateIndication; unsigned mAuxiliaryDataSizeLength; bool mHasAUHeader; uint32_t mAccessUnitRTPTime; uint32_t mAccessUnitRTPTime; bool mNextExpectedSeqNoValid; bool mNextExpectedSeqNoValid; Loading media/libstagefright/rtsp/APacketSource.cpp +83 −0 Original line number Original line Diff line number Diff line Loading @@ -247,6 +247,65 @@ sp<ABuffer> MakeAACCodecSpecificData(const char *params) { return csd; return csd; } } // From mpeg4-generic configuration data. sp<ABuffer> MakeAACCodecSpecificData2(const char *params) { AString val; unsigned long objectType; if (GetAttribute(params, "objectType", &val)) { const char *s = val.c_str(); char *end; objectType = strtoul(s, &end, 10); CHECK(end > s && *end == '\0'); } else { objectType = 0x40; // Audio ISO/IEC 14496-3 } CHECK(GetAttribute(params, "config", &val)); sp<ABuffer> config = decodeHex(val); CHECK(config != NULL); // Make sure size fits into a single byte and doesn't have to // be encoded. CHECK_LT(20 + config->size(), 128u); const uint8_t *data = config->data(); static const uint8_t kStaticESDS[] = { 0x03, 22, 0x00, 0x00, // ES_ID 0x00, // streamDependenceFlag, URL_Flag, OCRstreamFlag 0x04, 17, 0x40, // Audio ISO/IEC 14496-3 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 2, // AudioSpecificInfo follows }; sp<ABuffer> csd = new ABuffer(sizeof(kStaticESDS) + config->size()); uint8_t *dst = csd->data(); *dst++ = 0x03; *dst++ = 20 + config->size(); *dst++ = 0x00; // ES_ID *dst++ = 0x00; *dst++ = 0x00; // streamDependenceFlag, URL_Flag, OCRstreamFlag *dst++ = 0x04; *dst++ = 15 + config->size(); *dst++ = objectType; for (int i = 0; i < 12; ++i) { *dst++ = 0x00; } *dst++ = 0x05; *dst++ = config->size(); memcpy(dst, config->data(), config->size()); // hexdump(csd->data(), csd->size()); return csd; } static size_t GetSizeWidth(size_t x) { static size_t GetSizeWidth(size_t x) { size_t n = 1; size_t n = 1; while (x > 127) { while (x > 127) { Loading Loading @@ -560,6 +619,30 @@ APacketSource::APacketSource( mFormat->setInt32(kKeyWidth, width); mFormat->setInt32(kKeyWidth, width); mFormat->setInt32(kKeyHeight, height); mFormat->setInt32(kKeyHeight, height); } else if (!strncmp(desc.c_str(), "mpeg4-generic/", 14)) { AString val; if (!GetAttribute(params.c_str(), "mode", &val) || (strcasecmp(val.c_str(), "AAC-lbr") && strcasecmp(val.c_str(), "AAC-hbr"))) { mInitCheck = ERROR_UNSUPPORTED; return; } mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); int32_t sampleRate, numChannels; ASessionDescription::ParseFormatDesc( desc.c_str(), &sampleRate, &numChannels); mFormat->setInt32(kKeySampleRate, sampleRate); mFormat->setInt32(kKeyChannelCount, numChannels); sp<ABuffer> codecSpecificData = MakeAACCodecSpecificData2(params.c_str()); mFormat->setData( kKeyESDS, 0, codecSpecificData->data(), codecSpecificData->size()); } else { } else { mInitCheck = ERROR_UNSUPPORTED; mInitCheck = ERROR_UNSUPPORTED; } } Loading media/libstagefright/rtsp/ARTPSource.cpp +3 −2 Original line number Original line Diff line number Diff line Loading @@ -64,8 +64,9 @@ ARTPSource::ARTPSource( mAssembler = new AAMRAssembler(notify, false /* isWide */, params); mAssembler = new AAMRAssembler(notify, false /* isWide */, params); } else if (!strncmp(desc.c_str(), "AMR-WB/", 7)) { } else if (!strncmp(desc.c_str(), "AMR-WB/", 7)) { mAssembler = new AAMRAssembler(notify, true /* isWide */, params); mAssembler = new AAMRAssembler(notify, true /* isWide */, params); } else if (!strncmp(desc.c_str(), "MP4V-ES/", 8)) { } else if (!strncmp(desc.c_str(), "MP4V-ES/", 8) mAssembler = new AMPEG4ElementaryAssembler(notify); || !strncmp(desc.c_str(), "mpeg4-generic/", 14)) { mAssembler = new AMPEG4ElementaryAssembler(notify, desc, params); mIssueFIRRequests = true; mIssueFIRRequests = true; } else { } else { TRESPASS(); TRESPASS(); Loading Loading
media/libstagefright/rtsp/AMPEG4ElementaryAssembler.cpp +242 −3 Original line number Original line Diff line number Diff line Loading @@ -18,29 +18,160 @@ #include "ARTPSource.h" #include "ARTPSource.h" #include <media/stagefright/foundation/ABitReader.h> #include <media/stagefright/foundation/ABuffer.h> #include <media/stagefright/foundation/ABuffer.h> #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/AMessage.h> #include <media/stagefright/foundation/AMessage.h> #include <media/stagefright/foundation/hexdump.h> #include <media/stagefright/foundation/hexdump.h> #include <media/stagefright/Utils.h> #include <ctype.h> #include <stdint.h> #include <stdint.h> #define BE_VERBOSE 0 #define BE_VERBOSE 0 namespace android { namespace android { static bool GetAttribute(const char *s, const char *key, AString *value) { value->clear(); size_t keyLen = strlen(key); for (;;) { while (isspace(*s)) { ++s; } const char *colonPos = strchr(s, ';'); size_t len = (colonPos == NULL) ? strlen(s) : colonPos - s; if (len >= keyLen + 1 && s[keyLen] == '=' && !strncasecmp(s, key, keyLen)) { value->setTo(&s[keyLen + 1], len - keyLen - 1); return true; } if (colonPos == NULL) { return false; } s = colonPos + 1; } } static bool GetIntegerAttribute( const char *s, const char *key, unsigned *x) { *x = 0; AString val; if (!GetAttribute(s, key, &val)) { return false; } s = val.c_str(); char *end; unsigned y = strtoul(s, &end, 10); if (end == s || *end != '\0') { return false; } *x = y; return true; } // static // static AMPEG4ElementaryAssembler::AMPEG4ElementaryAssembler(const sp<AMessage> ¬ify) AMPEG4ElementaryAssembler::AMPEG4ElementaryAssembler( const sp<AMessage> ¬ify, const AString &desc, const AString ¶ms) : mNotifyMsg(notify), : mNotifyMsg(notify), mIsGeneric(false), mParams(params), mSizeLength(0), mIndexLength(0), mIndexDeltaLength(0), mCTSDeltaLength(0), mDTSDeltaLength(0), mRandomAccessIndication(false), mStreamStateIndication(0), mAuxiliaryDataSizeLength(0), mHasAUHeader(false), mAccessUnitRTPTime(0), mAccessUnitRTPTime(0), mNextExpectedSeqNoValid(false), mNextExpectedSeqNoValid(false), mNextExpectedSeqNo(0), mNextExpectedSeqNo(0), mAccessUnitDamaged(false) { mAccessUnitDamaged(false) { mIsGeneric = desc.startsWith("mpeg4-generic/"); if (mIsGeneric) { AString value; CHECK(GetAttribute(params.c_str(), "mode", &value)); if (!GetIntegerAttribute(params.c_str(), "sizeLength", &mSizeLength)) { mSizeLength = 0; } if (!GetIntegerAttribute( params.c_str(), "indexLength", &mIndexLength)) { mIndexLength = 0; } if (!GetIntegerAttribute( params.c_str(), "indexDeltaLength", &mIndexDeltaLength)) { mIndexDeltaLength = 0; } if (!GetIntegerAttribute( params.c_str(), "CTSDeltaLength", &mCTSDeltaLength)) { mCTSDeltaLength = 0; } if (!GetIntegerAttribute( params.c_str(), "DTSDeltaLength", &mDTSDeltaLength)) { mDTSDeltaLength = 0; } unsigned x; if (!GetIntegerAttribute( params.c_str(), "randomAccessIndication", &x)) { mRandomAccessIndication = false; } else { CHECK(x == 0 || x == 1); mRandomAccessIndication = (x != 0); } if (!GetIntegerAttribute( params.c_str(), "streamStateIndication", &mStreamStateIndication)) { mStreamStateIndication = 0; } if (!GetIntegerAttribute( params.c_str(), "auxiliaryDataSizeLength", &mAuxiliaryDataSizeLength)) { mAuxiliaryDataSizeLength = 0; } mHasAUHeader = mSizeLength > 0 || mIndexLength > 0 || mIndexDeltaLength > 0 || mCTSDeltaLength > 0 || mDTSDeltaLength > 0 || mRandomAccessIndication || mStreamStateIndication > 0; } } } AMPEG4ElementaryAssembler::~AMPEG4ElementaryAssembler() { AMPEG4ElementaryAssembler::~AMPEG4ElementaryAssembler() { } } struct AUHeader { unsigned mSize; unsigned mSerial; }; ARTPAssembler::AssemblyStatus AMPEG4ElementaryAssembler::addPacket( ARTPAssembler::AssemblyStatus AMPEG4ElementaryAssembler::addPacket( const sp<ARTPSource> &source) { const sp<ARTPSource> &source) { List<sp<ABuffer> > *queue = source->queue(); List<sp<ABuffer> > *queue = source->queue(); Loading Loading @@ -85,9 +216,117 @@ ARTPAssembler::AssemblyStatus AMPEG4ElementaryAssembler::addPacket( } } mAccessUnitRTPTime = rtpTime; mAccessUnitRTPTime = rtpTime; if (!mIsGeneric) { mPackets.push_back(buffer); mPackets.push_back(buffer); } else { // hexdump(buffer->data(), buffer->size()); // hexdump(buffer->data(), buffer->size()); CHECK_GE(buffer->size(), 2u); unsigned AU_headers_length = U16_AT(buffer->data()); // in bits CHECK_GE(buffer->size(), 2 + (AU_headers_length + 7) / 8); List<AUHeader> headers; ABitReader bits(buffer->data() + 2, buffer->size() - 2); unsigned numBitsLeft = AU_headers_length; unsigned AU_serial = 0; for (;;) { if (numBitsLeft < mSizeLength) { break; } unsigned AU_size = bits.getBits(mSizeLength); numBitsLeft -= mSizeLength; size_t n = headers.empty() ? mIndexLength : mIndexDeltaLength; if (numBitsLeft < n) { break; } unsigned AU_index = bits.getBits(n); numBitsLeft -= n; if (headers.empty()) { AU_serial = AU_index; } else { AU_serial += 1 + AU_index; } if (mCTSDeltaLength > 0) { if (numBitsLeft < 1) { break; } --numBitsLeft; if (bits.getBits(1)) { if (numBitsLeft < mCTSDeltaLength) { break; } bits.skipBits(mCTSDeltaLength); numBitsLeft -= mCTSDeltaLength; } } if (mDTSDeltaLength > 0) { if (numBitsLeft < 1) { break; } --numBitsLeft; if (bits.getBits(1)) { if (numBitsLeft < mDTSDeltaLength) { break; } bits.skipBits(mDTSDeltaLength); numBitsLeft -= mDTSDeltaLength; } } if (mRandomAccessIndication) { if (numBitsLeft < 1) { break; } bits.skipBits(1); --numBitsLeft; } if (mStreamStateIndication > 0) { if (numBitsLeft < mStreamStateIndication) { break; } bits.skipBits(mStreamStateIndication); } AUHeader header; header.mSize = AU_size; header.mSerial = AU_serial; headers.push_back(header); } size_t offset = 2 + (AU_headers_length + 7) / 8; if (mAuxiliaryDataSizeLength > 0) { ABitReader bits(buffer->data() + offset, buffer->size() - offset); unsigned auxSize = bits.getBits(mAuxiliaryDataSizeLength); offset += (mAuxiliaryDataSizeLength + auxSize + 7) / 8; } for (List<AUHeader>::iterator it = headers.begin(); it != headers.end(); ++it) { const AUHeader &header = *it; CHECK_LE(offset + header.mSize, buffer->size()); sp<ABuffer> accessUnit = new ABuffer(header.mSize); memcpy(accessUnit->data(), buffer->data() + offset, header.mSize); offset += header.mSize; CopyTimes(accessUnit, buffer); mPackets.push_back(accessUnit); } CHECK_EQ(offset, buffer->size()); } queue->erase(queue->begin()); queue->erase(queue->begin()); ++mNextExpectedSeqNo; ++mNextExpectedSeqNo; Loading
media/libstagefright/rtsp/AMPEG4ElementaryAssembler.h +17 −1 Original line number Original line Diff line number Diff line Loading @@ -20,6 +20,8 @@ #include "ARTPAssembler.h" #include "ARTPAssembler.h" #include <media/stagefright/foundation/AString.h> #include <utils/List.h> #include <utils/List.h> #include <utils/RefBase.h> #include <utils/RefBase.h> Loading @@ -29,7 +31,9 @@ struct ABuffer; struct AMessage; struct AMessage; struct AMPEG4ElementaryAssembler : public ARTPAssembler { struct AMPEG4ElementaryAssembler : public ARTPAssembler { AMPEG4ElementaryAssembler(const sp<AMessage> ¬ify); AMPEG4ElementaryAssembler( const sp<AMessage> ¬ify, const AString &desc, const AString ¶ms); protected: protected: virtual ~AMPEG4ElementaryAssembler(); virtual ~AMPEG4ElementaryAssembler(); Loading @@ -40,6 +44,18 @@ protected: private: private: sp<AMessage> mNotifyMsg; sp<AMessage> mNotifyMsg; bool mIsGeneric; AString mParams; unsigned mSizeLength; unsigned mIndexLength; unsigned mIndexDeltaLength; unsigned mCTSDeltaLength; unsigned mDTSDeltaLength; bool mRandomAccessIndication; unsigned mStreamStateIndication; unsigned mAuxiliaryDataSizeLength; bool mHasAUHeader; uint32_t mAccessUnitRTPTime; uint32_t mAccessUnitRTPTime; bool mNextExpectedSeqNoValid; bool mNextExpectedSeqNoValid; Loading
media/libstagefright/rtsp/APacketSource.cpp +83 −0 Original line number Original line Diff line number Diff line Loading @@ -247,6 +247,65 @@ sp<ABuffer> MakeAACCodecSpecificData(const char *params) { return csd; return csd; } } // From mpeg4-generic configuration data. sp<ABuffer> MakeAACCodecSpecificData2(const char *params) { AString val; unsigned long objectType; if (GetAttribute(params, "objectType", &val)) { const char *s = val.c_str(); char *end; objectType = strtoul(s, &end, 10); CHECK(end > s && *end == '\0'); } else { objectType = 0x40; // Audio ISO/IEC 14496-3 } CHECK(GetAttribute(params, "config", &val)); sp<ABuffer> config = decodeHex(val); CHECK(config != NULL); // Make sure size fits into a single byte and doesn't have to // be encoded. CHECK_LT(20 + config->size(), 128u); const uint8_t *data = config->data(); static const uint8_t kStaticESDS[] = { 0x03, 22, 0x00, 0x00, // ES_ID 0x00, // streamDependenceFlag, URL_Flag, OCRstreamFlag 0x04, 17, 0x40, // Audio ISO/IEC 14496-3 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 2, // AudioSpecificInfo follows }; sp<ABuffer> csd = new ABuffer(sizeof(kStaticESDS) + config->size()); uint8_t *dst = csd->data(); *dst++ = 0x03; *dst++ = 20 + config->size(); *dst++ = 0x00; // ES_ID *dst++ = 0x00; *dst++ = 0x00; // streamDependenceFlag, URL_Flag, OCRstreamFlag *dst++ = 0x04; *dst++ = 15 + config->size(); *dst++ = objectType; for (int i = 0; i < 12; ++i) { *dst++ = 0x00; } *dst++ = 0x05; *dst++ = config->size(); memcpy(dst, config->data(), config->size()); // hexdump(csd->data(), csd->size()); return csd; } static size_t GetSizeWidth(size_t x) { static size_t GetSizeWidth(size_t x) { size_t n = 1; size_t n = 1; while (x > 127) { while (x > 127) { Loading Loading @@ -560,6 +619,30 @@ APacketSource::APacketSource( mFormat->setInt32(kKeyWidth, width); mFormat->setInt32(kKeyWidth, width); mFormat->setInt32(kKeyHeight, height); mFormat->setInt32(kKeyHeight, height); } else if (!strncmp(desc.c_str(), "mpeg4-generic/", 14)) { AString val; if (!GetAttribute(params.c_str(), "mode", &val) || (strcasecmp(val.c_str(), "AAC-lbr") && strcasecmp(val.c_str(), "AAC-hbr"))) { mInitCheck = ERROR_UNSUPPORTED; return; } mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); int32_t sampleRate, numChannels; ASessionDescription::ParseFormatDesc( desc.c_str(), &sampleRate, &numChannels); mFormat->setInt32(kKeySampleRate, sampleRate); mFormat->setInt32(kKeyChannelCount, numChannels); sp<ABuffer> codecSpecificData = MakeAACCodecSpecificData2(params.c_str()); mFormat->setData( kKeyESDS, 0, codecSpecificData->data(), codecSpecificData->size()); } else { } else { mInitCheck = ERROR_UNSUPPORTED; mInitCheck = ERROR_UNSUPPORTED; } } Loading
media/libstagefright/rtsp/ARTPSource.cpp +3 −2 Original line number Original line Diff line number Diff line Loading @@ -64,8 +64,9 @@ ARTPSource::ARTPSource( mAssembler = new AAMRAssembler(notify, false /* isWide */, params); mAssembler = new AAMRAssembler(notify, false /* isWide */, params); } else if (!strncmp(desc.c_str(), "AMR-WB/", 7)) { } else if (!strncmp(desc.c_str(), "AMR-WB/", 7)) { mAssembler = new AAMRAssembler(notify, true /* isWide */, params); mAssembler = new AAMRAssembler(notify, true /* isWide */, params); } else if (!strncmp(desc.c_str(), "MP4V-ES/", 8)) { } else if (!strncmp(desc.c_str(), "MP4V-ES/", 8) mAssembler = new AMPEG4ElementaryAssembler(notify); || !strncmp(desc.c_str(), "mpeg4-generic/", 14)) { mAssembler = new AMPEG4ElementaryAssembler(notify, desc, params); mIssueFIRRequests = true; mIssueFIRRequests = true; } else { } else { TRESPASS(); TRESPASS(); Loading