Loading media/extractors/mp4/MPEG4Extractor.cpp +34 −9 Original line number Diff line number Diff line Loading @@ -113,6 +113,7 @@ private: const Trex *mTrex; off64_t mFirstMoofOffset; off64_t mCurrentMoofOffset; off64_t mCurrentMoofSize; off64_t mNextMoofOffset; uint32_t mCurrentTime; // in media timescale ticks int32_t mLastParsedTrackId; Loading Loading @@ -165,8 +166,9 @@ private: status_t parseTrackFragmentRun(off64_t offset, off64_t size); status_t parseSampleAuxiliaryInformationSizes(off64_t offset, off64_t size); status_t parseSampleAuxiliaryInformationOffsets(off64_t offset, off64_t size); status_t parseClearEncryptedSizes(off64_t offset, bool isSubsampleEncryption, uint32_t flags); status_t parseSampleEncryption(off64_t offset); status_t parseClearEncryptedSizes(off64_t offset, bool isSampleEncryption, uint32_t flags, off64_t size); status_t parseSampleEncryption(off64_t offset, off64_t size); // returns -1 for invalid layer ID int32_t parseHEVCLayerId(const uint8_t *data, size_t size); Loading Loading @@ -4859,6 +4861,7 @@ MPEG4Source::MPEG4Source( mTrex(trex), mFirstMoofOffset(firstMoofOffset), mCurrentMoofOffset(firstMoofOffset), mCurrentMoofSize(0), mNextMoofOffset(-1), mCurrentTime(0), mDefaultEncryptedByteBlock(0), Loading Loading @@ -5109,6 +5112,9 @@ status_t MPEG4Source::parseChunk(off64_t *offset) { case FOURCC("moof"): { off64_t stop_offset = *offset + chunk_size; *offset = data_offset; if (chunk_type == FOURCC("moof")) { mCurrentMoofSize = chunk_data_size; } while (*offset < stop_offset) { status_t err = parseChunk(offset); if (err != OK) { Loading Loading @@ -5197,7 +5203,7 @@ status_t MPEG4Source::parseChunk(off64_t *offset) { case FOURCC("senc"): { status_t err; if ((err = parseSampleEncryption(data_offset)) != OK) { if ((err = parseSampleEncryption(data_offset, chunk_data_size)) != OK) { return err; } *offset += chunk_size; Loading Loading @@ -5390,11 +5396,11 @@ status_t MPEG4Source::parseSampleAuxiliaryInformationOffsets( drmoffset += mCurrentMoofOffset; return parseClearEncryptedSizes(drmoffset, false, 0); return parseClearEncryptedSizes(drmoffset, false, 0, mCurrentMoofSize); } status_t MPEG4Source::parseClearEncryptedSizes( off64_t offset, bool isSubsampleEncryption, uint32_t flags) { off64_t offset, bool isSampleEncryption, uint32_t flags, off64_t size) { int32_t ivlength; if (!AMediaFormat_getInt32(mFormat, AMEDIAFORMAT_KEY_CRYPTO_DEFAULT_IV_SIZE, &ivlength)) { Loading @@ -5408,11 +5414,15 @@ status_t MPEG4Source::parseClearEncryptedSizes( } uint32_t sampleCount = mCurrentSampleInfoCount; if (isSubsampleEncryption) { if (isSampleEncryption) { if (size < 4) { return ERROR_MALFORMED; } if (!mDataSource->getUInt32(offset, &sampleCount)) { return ERROR_IO; } offset += 4; size -= 4; } // read CencSampleAuxiliaryDataFormats Loading @@ -5427,14 +5437,18 @@ status_t MPEG4Source::parseClearEncryptedSizes( } memset(smpl->iv, 0, 16); if (size < ivlength) { return ERROR_MALFORMED; } if (mDataSource->readAt(offset, smpl->iv, ivlength) != ivlength) { return ERROR_IO; } offset += ivlength; size -= ivlength; bool readSubsamples; if (isSubsampleEncryption) { if (isSampleEncryption) { readSubsamples = flags & 2; } else { int32_t smplinfosize = mCurrentDefaultSampleInfoSize; Loading @@ -5446,13 +5460,20 @@ status_t MPEG4Source::parseClearEncryptedSizes( if (readSubsamples) { uint16_t numsubsamples; if (size < 2) { return ERROR_MALFORMED; } if (!mDataSource->getUInt16(offset, &numsubsamples)) { return ERROR_IO; } offset += 2; size -= 2; for (size_t j = 0; j < numsubsamples; j++) { uint16_t numclear; uint32_t numencrypted; if (size < 6) { return ERROR_MALFORMED; } if (!mDataSource->getUInt16(offset, &numclear)) { return ERROR_IO; } Loading @@ -5461,6 +5482,7 @@ status_t MPEG4Source::parseClearEncryptedSizes( return ERROR_IO; } offset += 4; size -= 6; smpl->clearsizes.add(numclear); smpl->encryptedsizes.add(numencrypted); } Loading @@ -5473,12 +5495,15 @@ status_t MPEG4Source::parseClearEncryptedSizes( return OK; } status_t MPEG4Source::parseSampleEncryption(off64_t offset) { status_t MPEG4Source::parseSampleEncryption(off64_t offset, off64_t chunk_data_size) { uint32_t flags; if (chunk_data_size < 4) { return ERROR_MALFORMED; } if (!mDataSource->getUInt32(offset, &flags)) { // actually version + flags return ERROR_MALFORMED; } return parseClearEncryptedSizes(offset + 4, true, flags); return parseClearEncryptedSizes(offset + 4, true, flags, chunk_data_size - 4); } status_t MPEG4Source::parseTrackFragmentHeader(off64_t offset, off64_t size) { Loading media/libaaudio/src/client/AudioStreamInternal.cpp +5 −7 Original line number Diff line number Diff line Loading @@ -714,12 +714,8 @@ void AudioStreamInternal::processTimestamp(uint64_t position, int64_t time) { aaudio_result_t AudioStreamInternal::setBufferSize(int32_t requestedFrames) { int32_t adjustedFrames = requestedFrames; const int32_t maximumSize = getBufferCapacity() - mFramesPerBurst; // The buffer size can be set to zero. // This means that the callback may be called when the internal buffer becomes empty. // This will be fine on some devices in ideal circumstances and will result in the // lowest possible latency. // If there are glitches then they should be detected as XRuns and the size can be increased. static const int32_t minimumSize = 0; // Minimum size should be a multiple number of bursts. const int32_t minimumSize = 1 * mFramesPerBurst; // Clip to minimum size so that rounding up will work better. adjustedFrames = std::max(minimumSize, adjustedFrames); Loading @@ -731,12 +727,14 @@ aaudio_result_t AudioStreamInternal::setBufferSize(int32_t requestedFrames) { // Round to the next highest burst size. int32_t numBursts = (adjustedFrames + mFramesPerBurst - 1) / mFramesPerBurst; adjustedFrames = numBursts * mFramesPerBurst; // Clip just in case maximumSize is not a multiple of mFramesPerBurst. adjustedFrames = std::min(maximumSize, adjustedFrames); } // Clip against the actual size from the endpoint. int32_t actualFrames = 0; mAudioEndpoint.setBufferSizeInFrames(maximumSize, &actualFrames); // actualFrames should be <= maximumSize // actualFrames should be <= actual maximum size of endpoint adjustedFrames = std::min(actualFrames, adjustedFrames); mBufferSizeInFrames = adjustedFrames; Loading media/libaaudio/src/client/IsochronousClockModel.cpp +2 −4 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ IsochronousClockModel::IsochronousClockModel() , mMarkerNanoTime(0) , mSampleRate(48000) , mFramesPerBurst(48) , mBurstPeriodNanos(0) // this will be updated before use , mMaxMeasuredLatenessNanos(0) , mLatenessForDriftNanos(kInitialLatenessForDriftNanos) , mState(STATE_STOPPED) Loading @@ -57,9 +58,6 @@ IsochronousClockModel::IsochronousClockModel() } } IsochronousClockModel::~IsochronousClockModel() { } void IsochronousClockModel::setPositionAndTime(int64_t framePosition, int64_t nanoTime) { ALOGV("setPositionAndTime, %lld, %lld", (long long) framePosition, (long long) nanoTime); mMarkerFramePosition = framePosition; Loading Loading @@ -186,7 +184,7 @@ void IsochronousClockModel::processTimestamp(int64_t framePosition, int64_t nano // Calculate upper region that will trigger a drift forwards. mLatenessForDriftNanos = mMaxMeasuredLatenessNanos - (mMaxMeasuredLatenessNanos >> 4); } else { // decrease // If these is an outlier in lateness then mMaxMeasuredLatenessNanos can go high // If this is an outlier in lateness then mMaxMeasuredLatenessNanos can go high // and stay there. So we slowly reduce mMaxMeasuredLatenessNanos for better // long term stability. The two opposing forces will keep mMaxMeasuredLatenessNanos // within a reasonable range. Loading media/libaaudio/src/client/IsochronousClockModel.h +2 −2 Original line number Diff line number Diff line Loading @@ -35,7 +35,7 @@ class IsochronousClockModel { public: IsochronousClockModel(); virtual ~IsochronousClockModel(); virtual ~IsochronousClockModel() = default; void start(int64_t nanoTime); void stop(int64_t nanoTime); Loading Loading @@ -130,6 +130,7 @@ public: private: int32_t getLateTimeOffsetNanos() const; void update(); enum clock_model_state_t { STATE_STOPPED, Loading Loading @@ -164,7 +165,6 @@ private: // distribution of timestamps relative to earliest std::unique_ptr<android::audio_utils::Histogram> mHistogramMicros; void update(); }; } /* namespace aaudio */ Loading media/libmediametrics/include/media/MediaMetricsItem.h +6 −6 Original line number Diff line number Diff line Loading @@ -223,7 +223,7 @@ static inline bool startsWith(const std::string& s, const std::string& comp) { class Defer { public: template <typename U> Defer(U &&f) : mThunk(std::forward<U>(f)) {} explicit Defer(U &&f) : mThunk(std::forward<U>(f)) {} ~Defer() { mThunk(); } private: Loading Loading @@ -522,7 +522,7 @@ public: BufferedItem(const BufferedItem&) = delete; BufferedItem& operator=(const BufferedItem&) = delete; BufferedItem(const std::string key, char *begin, char *end) BufferedItem(const std::string& key, char *begin, char *end) : BufferedItem(key.c_str(), begin, end) { } BufferedItem(const char *key, char *begin, char *end) Loading Loading @@ -687,7 +687,7 @@ protected: template <size_t N = 4096> class LogItem : public BufferedItem { public: explicit LogItem(const std::string key) : LogItem(key.c_str()) { } explicit LogItem(const std::string& key) : LogItem(key.c_str()) { } // Since this class will not be defined before the base class, we initialize variables // in our own order. Loading Loading @@ -742,10 +742,10 @@ public: mElem = other.mElem; return *this; } Prop(Prop&& other) { Prop(Prop&& other) noexcept { *this = std::move(other); } Prop& operator=(Prop&& other) { Prop& operator=(Prop&& other) noexcept { mName = std::move(other.mName); mElem = std::move(other.mElem); return *this; Loading Loading @@ -856,7 +856,7 @@ public: // Iteration of props within item class iterator { public: iterator(const std::map<std::string, Prop>::const_iterator &_it) : it(_it) { } explicit iterator(const std::map<std::string, Prop>::const_iterator &_it) : it(_it) { } iterator &operator++() { ++it; return *this; Loading Loading
media/extractors/mp4/MPEG4Extractor.cpp +34 −9 Original line number Diff line number Diff line Loading @@ -113,6 +113,7 @@ private: const Trex *mTrex; off64_t mFirstMoofOffset; off64_t mCurrentMoofOffset; off64_t mCurrentMoofSize; off64_t mNextMoofOffset; uint32_t mCurrentTime; // in media timescale ticks int32_t mLastParsedTrackId; Loading Loading @@ -165,8 +166,9 @@ private: status_t parseTrackFragmentRun(off64_t offset, off64_t size); status_t parseSampleAuxiliaryInformationSizes(off64_t offset, off64_t size); status_t parseSampleAuxiliaryInformationOffsets(off64_t offset, off64_t size); status_t parseClearEncryptedSizes(off64_t offset, bool isSubsampleEncryption, uint32_t flags); status_t parseSampleEncryption(off64_t offset); status_t parseClearEncryptedSizes(off64_t offset, bool isSampleEncryption, uint32_t flags, off64_t size); status_t parseSampleEncryption(off64_t offset, off64_t size); // returns -1 for invalid layer ID int32_t parseHEVCLayerId(const uint8_t *data, size_t size); Loading Loading @@ -4859,6 +4861,7 @@ MPEG4Source::MPEG4Source( mTrex(trex), mFirstMoofOffset(firstMoofOffset), mCurrentMoofOffset(firstMoofOffset), mCurrentMoofSize(0), mNextMoofOffset(-1), mCurrentTime(0), mDefaultEncryptedByteBlock(0), Loading Loading @@ -5109,6 +5112,9 @@ status_t MPEG4Source::parseChunk(off64_t *offset) { case FOURCC("moof"): { off64_t stop_offset = *offset + chunk_size; *offset = data_offset; if (chunk_type == FOURCC("moof")) { mCurrentMoofSize = chunk_data_size; } while (*offset < stop_offset) { status_t err = parseChunk(offset); if (err != OK) { Loading Loading @@ -5197,7 +5203,7 @@ status_t MPEG4Source::parseChunk(off64_t *offset) { case FOURCC("senc"): { status_t err; if ((err = parseSampleEncryption(data_offset)) != OK) { if ((err = parseSampleEncryption(data_offset, chunk_data_size)) != OK) { return err; } *offset += chunk_size; Loading Loading @@ -5390,11 +5396,11 @@ status_t MPEG4Source::parseSampleAuxiliaryInformationOffsets( drmoffset += mCurrentMoofOffset; return parseClearEncryptedSizes(drmoffset, false, 0); return parseClearEncryptedSizes(drmoffset, false, 0, mCurrentMoofSize); } status_t MPEG4Source::parseClearEncryptedSizes( off64_t offset, bool isSubsampleEncryption, uint32_t flags) { off64_t offset, bool isSampleEncryption, uint32_t flags, off64_t size) { int32_t ivlength; if (!AMediaFormat_getInt32(mFormat, AMEDIAFORMAT_KEY_CRYPTO_DEFAULT_IV_SIZE, &ivlength)) { Loading @@ -5408,11 +5414,15 @@ status_t MPEG4Source::parseClearEncryptedSizes( } uint32_t sampleCount = mCurrentSampleInfoCount; if (isSubsampleEncryption) { if (isSampleEncryption) { if (size < 4) { return ERROR_MALFORMED; } if (!mDataSource->getUInt32(offset, &sampleCount)) { return ERROR_IO; } offset += 4; size -= 4; } // read CencSampleAuxiliaryDataFormats Loading @@ -5427,14 +5437,18 @@ status_t MPEG4Source::parseClearEncryptedSizes( } memset(smpl->iv, 0, 16); if (size < ivlength) { return ERROR_MALFORMED; } if (mDataSource->readAt(offset, smpl->iv, ivlength) != ivlength) { return ERROR_IO; } offset += ivlength; size -= ivlength; bool readSubsamples; if (isSubsampleEncryption) { if (isSampleEncryption) { readSubsamples = flags & 2; } else { int32_t smplinfosize = mCurrentDefaultSampleInfoSize; Loading @@ -5446,13 +5460,20 @@ status_t MPEG4Source::parseClearEncryptedSizes( if (readSubsamples) { uint16_t numsubsamples; if (size < 2) { return ERROR_MALFORMED; } if (!mDataSource->getUInt16(offset, &numsubsamples)) { return ERROR_IO; } offset += 2; size -= 2; for (size_t j = 0; j < numsubsamples; j++) { uint16_t numclear; uint32_t numencrypted; if (size < 6) { return ERROR_MALFORMED; } if (!mDataSource->getUInt16(offset, &numclear)) { return ERROR_IO; } Loading @@ -5461,6 +5482,7 @@ status_t MPEG4Source::parseClearEncryptedSizes( return ERROR_IO; } offset += 4; size -= 6; smpl->clearsizes.add(numclear); smpl->encryptedsizes.add(numencrypted); } Loading @@ -5473,12 +5495,15 @@ status_t MPEG4Source::parseClearEncryptedSizes( return OK; } status_t MPEG4Source::parseSampleEncryption(off64_t offset) { status_t MPEG4Source::parseSampleEncryption(off64_t offset, off64_t chunk_data_size) { uint32_t flags; if (chunk_data_size < 4) { return ERROR_MALFORMED; } if (!mDataSource->getUInt32(offset, &flags)) { // actually version + flags return ERROR_MALFORMED; } return parseClearEncryptedSizes(offset + 4, true, flags); return parseClearEncryptedSizes(offset + 4, true, flags, chunk_data_size - 4); } status_t MPEG4Source::parseTrackFragmentHeader(off64_t offset, off64_t size) { Loading
media/libaaudio/src/client/AudioStreamInternal.cpp +5 −7 Original line number Diff line number Diff line Loading @@ -714,12 +714,8 @@ void AudioStreamInternal::processTimestamp(uint64_t position, int64_t time) { aaudio_result_t AudioStreamInternal::setBufferSize(int32_t requestedFrames) { int32_t adjustedFrames = requestedFrames; const int32_t maximumSize = getBufferCapacity() - mFramesPerBurst; // The buffer size can be set to zero. // This means that the callback may be called when the internal buffer becomes empty. // This will be fine on some devices in ideal circumstances and will result in the // lowest possible latency. // If there are glitches then they should be detected as XRuns and the size can be increased. static const int32_t minimumSize = 0; // Minimum size should be a multiple number of bursts. const int32_t minimumSize = 1 * mFramesPerBurst; // Clip to minimum size so that rounding up will work better. adjustedFrames = std::max(minimumSize, adjustedFrames); Loading @@ -731,12 +727,14 @@ aaudio_result_t AudioStreamInternal::setBufferSize(int32_t requestedFrames) { // Round to the next highest burst size. int32_t numBursts = (adjustedFrames + mFramesPerBurst - 1) / mFramesPerBurst; adjustedFrames = numBursts * mFramesPerBurst; // Clip just in case maximumSize is not a multiple of mFramesPerBurst. adjustedFrames = std::min(maximumSize, adjustedFrames); } // Clip against the actual size from the endpoint. int32_t actualFrames = 0; mAudioEndpoint.setBufferSizeInFrames(maximumSize, &actualFrames); // actualFrames should be <= maximumSize // actualFrames should be <= actual maximum size of endpoint adjustedFrames = std::min(actualFrames, adjustedFrames); mBufferSizeInFrames = adjustedFrames; Loading
media/libaaudio/src/client/IsochronousClockModel.cpp +2 −4 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ IsochronousClockModel::IsochronousClockModel() , mMarkerNanoTime(0) , mSampleRate(48000) , mFramesPerBurst(48) , mBurstPeriodNanos(0) // this will be updated before use , mMaxMeasuredLatenessNanos(0) , mLatenessForDriftNanos(kInitialLatenessForDriftNanos) , mState(STATE_STOPPED) Loading @@ -57,9 +58,6 @@ IsochronousClockModel::IsochronousClockModel() } } IsochronousClockModel::~IsochronousClockModel() { } void IsochronousClockModel::setPositionAndTime(int64_t framePosition, int64_t nanoTime) { ALOGV("setPositionAndTime, %lld, %lld", (long long) framePosition, (long long) nanoTime); mMarkerFramePosition = framePosition; Loading Loading @@ -186,7 +184,7 @@ void IsochronousClockModel::processTimestamp(int64_t framePosition, int64_t nano // Calculate upper region that will trigger a drift forwards. mLatenessForDriftNanos = mMaxMeasuredLatenessNanos - (mMaxMeasuredLatenessNanos >> 4); } else { // decrease // If these is an outlier in lateness then mMaxMeasuredLatenessNanos can go high // If this is an outlier in lateness then mMaxMeasuredLatenessNanos can go high // and stay there. So we slowly reduce mMaxMeasuredLatenessNanos for better // long term stability. The two opposing forces will keep mMaxMeasuredLatenessNanos // within a reasonable range. Loading
media/libaaudio/src/client/IsochronousClockModel.h +2 −2 Original line number Diff line number Diff line Loading @@ -35,7 +35,7 @@ class IsochronousClockModel { public: IsochronousClockModel(); virtual ~IsochronousClockModel(); virtual ~IsochronousClockModel() = default; void start(int64_t nanoTime); void stop(int64_t nanoTime); Loading Loading @@ -130,6 +130,7 @@ public: private: int32_t getLateTimeOffsetNanos() const; void update(); enum clock_model_state_t { STATE_STOPPED, Loading Loading @@ -164,7 +165,6 @@ private: // distribution of timestamps relative to earliest std::unique_ptr<android::audio_utils::Histogram> mHistogramMicros; void update(); }; } /* namespace aaudio */ Loading
media/libmediametrics/include/media/MediaMetricsItem.h +6 −6 Original line number Diff line number Diff line Loading @@ -223,7 +223,7 @@ static inline bool startsWith(const std::string& s, const std::string& comp) { class Defer { public: template <typename U> Defer(U &&f) : mThunk(std::forward<U>(f)) {} explicit Defer(U &&f) : mThunk(std::forward<U>(f)) {} ~Defer() { mThunk(); } private: Loading Loading @@ -522,7 +522,7 @@ public: BufferedItem(const BufferedItem&) = delete; BufferedItem& operator=(const BufferedItem&) = delete; BufferedItem(const std::string key, char *begin, char *end) BufferedItem(const std::string& key, char *begin, char *end) : BufferedItem(key.c_str(), begin, end) { } BufferedItem(const char *key, char *begin, char *end) Loading Loading @@ -687,7 +687,7 @@ protected: template <size_t N = 4096> class LogItem : public BufferedItem { public: explicit LogItem(const std::string key) : LogItem(key.c_str()) { } explicit LogItem(const std::string& key) : LogItem(key.c_str()) { } // Since this class will not be defined before the base class, we initialize variables // in our own order. Loading Loading @@ -742,10 +742,10 @@ public: mElem = other.mElem; return *this; } Prop(Prop&& other) { Prop(Prop&& other) noexcept { *this = std::move(other); } Prop& operator=(Prop&& other) { Prop& operator=(Prop&& other) noexcept { mName = std::move(other.mName); mElem = std::move(other.mElem); return *this; Loading Loading @@ -856,7 +856,7 @@ public: // Iteration of props within item class iterator { public: iterator(const std::map<std::string, Prop>::const_iterator &_it) : it(_it) { } explicit iterator(const std::map<std::string, Prop>::const_iterator &_it) : it(_it) { } iterator &operator++() { ++it; return *this; Loading