Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 142598f2 authored by Sampath Shetty's avatar Sampath Shetty Committed by Mikhail Naganov
Browse files

Handle audio presentation switching in AC-4 TS

Audio preselection descriptors(APD) can switch mid-stream in AC-4 TS.
Detect change in APD by monitoring PMT version & CRC. Update new
audio presentation information to the stream metadata so that
MediaExtractor.getAudioPresentations() always returns a latest
audio presentation available.

Bug: 63901775
Bug: 119312182
Test: atest android.media.cts.MediaExtractorTest#testGetAudioPresentations
Change-Id: I7f29de6fb90b4ac1bddd4ddb47f83d35dc7f2345
parent 04228920
Loading
Loading
Loading
Loading
+25 −2
Original line number Original line Diff line number Diff line
@@ -121,6 +121,8 @@ private:
    ATSParser *mParser;
    ATSParser *mParser;
    unsigned mProgramNumber;
    unsigned mProgramNumber;
    unsigned mProgramMapPID;
    unsigned mProgramMapPID;
    uint32_t mPMTVersion;
    uint32_t mPMT_CRC;
    KeyedVector<unsigned, sp<Stream> > mStreams;
    KeyedVector<unsigned, sp<Stream> > mStreams;
    bool mFirstPTSValid;
    bool mFirstPTSValid;
    uint64_t mFirstPTS;
    uint64_t mFirstPTS;
@@ -143,6 +145,9 @@ struct ATSParser::Stream : public RefBase {
    unsigned typeExt() const { return mStreamTypeExt; }
    unsigned typeExt() const { return mStreamTypeExt; }
    unsigned pid() const { return mElementaryPID; }
    unsigned pid() const { return mElementaryPID; }
    void setPID(unsigned pid) { mElementaryPID = pid; }
    void setPID(unsigned pid) { mElementaryPID = pid; }
    void setAudioPresentations(AudioPresentationCollection audioPresentations) {
        mAudioPresentations = audioPresentations;
    }


    void setCasInfo(
    void setCasInfo(
            int32_t systemId,
            int32_t systemId,
@@ -293,6 +298,8 @@ ATSParser::Program::Program(
    : mParser(parser),
    : mParser(parser),
      mProgramNumber(programNumber),
      mProgramNumber(programNumber),
      mProgramMapPID(programMapPID),
      mProgramMapPID(programMapPID),
      mPMTVersion(0xffffffff),
      mPMT_CRC(0xffffffff),
      mFirstPTSValid(false),
      mFirstPTSValid(false),
      mFirstPTS(0),
      mFirstPTS(0),
      mLastRecoveredPTS(lastRecoveredPTS) {
      mLastRecoveredPTS(lastRecoveredPTS) {
@@ -480,7 +487,13 @@ status_t ATSParser::Program::parseProgramMap(ABitReader *br) {


    MY_LOGV("  program_number = %u", br->getBits(16));
    MY_LOGV("  program_number = %u", br->getBits(16));
    MY_LOGV("  reserved = %u", br->getBits(2));
    MY_LOGV("  reserved = %u", br->getBits(2));
    MY_LOGV("  version_number = %u", br->getBits(5));
    bool audioPresentationsChanged = false;
    unsigned pmtVersion = br->getBits(5);
    if (pmtVersion != mPMTVersion) {
        audioPresentationsChanged = true;
        mPMTVersion = pmtVersion;
    }
    MY_LOGV("  version_number = %u", pmtVersion);
    MY_LOGV("  current_next_indicator = %u", br->getBits(1));
    MY_LOGV("  current_next_indicator = %u", br->getBits(1));
    MY_LOGV("  section_number = %u", br->getBits(8));
    MY_LOGV("  section_number = %u", br->getBits(8));
    MY_LOGV("  last_section_number = %u", br->getBits(8));
    MY_LOGV("  last_section_number = %u", br->getBits(8));
@@ -661,7 +674,12 @@ status_t ATSParser::Program::parseProgramMap(ABitReader *br) {
    if (infoBytesRemaining != 0) {
    if (infoBytesRemaining != 0) {
        ALOGW("Section data remains unconsumed");
        ALOGW("Section data remains unconsumed");
    }
    }
    MY_LOGV("  CRC = 0x%08x", br->getBits(32));
    unsigned crc = br->getBits(32);
    if (crc != mPMT_CRC) {
        audioPresentationsChanged = true;
        mPMT_CRC = crc;
    }
    MY_LOGV("  CRC = 0x%08x", crc);


    bool PIDsChanged = false;
    bool PIDsChanged = false;
    for (size_t i = 0; i < infos.size(); ++i) {
    for (size_t i = 0; i < infos.size(); ++i) {
@@ -722,6 +740,10 @@ status_t ATSParser::Program::parseProgramMap(ABitReader *br) {
            isAddingScrambledStream |= info.mCADescriptor.mSystemID >= 0;
            isAddingScrambledStream |= info.mCADescriptor.mSystemID >= 0;
            mStreams.add(info.mPID, stream);
            mStreams.add(info.mPID, stream);
        }
        }
        else if (index >= 0 && mStreams.editValueAt(index)->isAudio()
                 && audioPresentationsChanged) {
            mStreams.editValueAt(index)->setAudioPresentations(info.mAudioPresentations);
        }
    }
    }


    if (isAddingScrambledStream) {
    if (isAddingScrambledStream) {
@@ -1732,6 +1754,7 @@ void ATSParser::Stream::onPayloadData(
                mSource->setFormat(mQueue->getFormat());
                mSource->setFormat(mQueue->getFormat());
            }
            }
            mSource->queueAccessUnit(accessUnit);
            mSource->queueAccessUnit(accessUnit);
            mSource->convertAudioPresentationInfoToMetadata(mAudioPresentations);
        }
        }


        // Every access unit has a pesStartOffset queued in |mPesStartOffsets|.
        // Every access unit has a pesStartOffset queued in |mPesStartOffsets|.