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

Commit f4bc76e1 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "MediaCas: re-send the first scrambled TS packet to decoder"

parents 4aa394d1 b2451bb3
Loading
Loading
Loading
Loading
+15 −2
Original line number Original line Diff line number Diff line
@@ -129,6 +129,7 @@ status_t ACodecBufferChannel::queueSecureInputBuffer(
        secureHandle = static_cast<native_handle_t *>(secureData->getDestinationPointer());
        secureHandle = static_cast<native_handle_t *>(secureData->getDestinationPointer());
    }
    }
    ssize_t result = -1;
    ssize_t result = -1;
    ssize_t codecDataOffset = 0;
    if (mCrypto != NULL) {
    if (mCrypto != NULL) {
        ICrypto::DestinationBuffer destination;
        ICrypto::DestinationBuffer destination;
        if (secure) {
        if (secure) {
@@ -180,9 +181,16 @@ status_t ACodecBufferChannel::queueSecureInputBuffer(


        Status status = Status::OK;
        Status status = Status::OK;
        hidl_string detailedError;
        hidl_string detailedError;
        ScramblingControl sctrl = ScramblingControl::UNSCRAMBLED;

        if (key != NULL) {
            sctrl = (ScramblingControl)key[0];
            // Adjust for the PES offset
            codecDataOffset = key[2] | (key[3] << 8);
        }


        auto returnVoid = mDescrambler->descramble(
        auto returnVoid = mDescrambler->descramble(
                key != NULL ? (ScramblingControl)key[0] : ScramblingControl::UNSCRAMBLED,
                sctrl,
                hidlSubSamples,
                hidlSubSamples,
                srcBuffer,
                srcBuffer,
                0,
                0,
@@ -202,6 +210,11 @@ status_t ACodecBufferChannel::queueSecureInputBuffer(
            return UNKNOWN_ERROR;
            return UNKNOWN_ERROR;
        }
        }


        if (result < codecDataOffset) {
            ALOGD("invalid codec data offset: %zd, result %zd", codecDataOffset, result);
            return BAD_VALUE;
        }

        ALOGV("descramble succeeded, %zd bytes", result);
        ALOGV("descramble succeeded, %zd bytes", result);


        if (dstBuffer.type == BufferType::SHARED_MEMORY) {
        if (dstBuffer.type == BufferType::SHARED_MEMORY) {
@@ -210,7 +223,7 @@ status_t ACodecBufferChannel::queueSecureInputBuffer(
        }
        }
    }
    }


    it->mCodecBuffer->setRange(0, result);
    it->mCodecBuffer->setRange(codecDataOffset, result - codecDataOffset);


    // Copy metadata from client to codec buffer.
    // Copy metadata from client to codec buffer.
    it->mCodecBuffer->meta()->clear();
    it->mCodecBuffer->meta()->clear();
+26 −10
Original line number Original line Diff line number Diff line
@@ -1437,7 +1437,7 @@ status_t ATSParser::Stream::flushScrambled(SyncEvent *event) {
    // Perform the 1st pass descrambling if needed
    // Perform the 1st pass descrambling if needed
    if (descrambleBytes > 0) {
    if (descrambleBytes > 0) {
        memcpy(mDescrambledBuffer->data(), mBuffer->data(), descrambleBytes);
        memcpy(mDescrambledBuffer->data(), mBuffer->data(), descrambleBytes);
        mDescrambledBuffer->setRange(0, descrambleBytes);
        mDescrambledBuffer->setRange(0, mBuffer->size());


        hidl_vec<SubSample> subSamples;
        hidl_vec<SubSample> subSamples;
        subSamples.resize(descrambleSubSamples);
        subSamples.resize(descrambleSubSamples);
@@ -1454,10 +1454,9 @@ status_t ATSParser::Stream::flushScrambled(SyncEvent *event) {
            }
            }
        }
        }


        uint64_t srcOffset = 0, dstOffset = 0;
        // If scrambled at PES-level, PES header is in the clear
        // If scrambled at PES-level, PES header should be skipped
        if (pesScramblingControl != 0) {
        if (pesScramblingControl != 0) {
            srcOffset = dstOffset = pesOffset;
            subSamples[0].numBytesOfClearData = pesOffset;
            subSamples[0].numBytesOfEncryptedData -= pesOffset;
            subSamples[0].numBytesOfEncryptedData -= pesOffset;
        }
        }


@@ -1473,9 +1472,9 @@ status_t ATSParser::Stream::flushScrambled(SyncEvent *event) {
                (ScramblingControl) sctrl,
                (ScramblingControl) sctrl,
                subSamples,
                subSamples,
                mDescramblerSrcBuffer,
                mDescramblerSrcBuffer,
                srcOffset,
                0 /*srcOffset*/,
                dstBuffer,
                dstBuffer,
                dstOffset,
                0 /*dstOffset*/,
                [&status, &bytesWritten, &detailedError] (
                [&status, &bytesWritten, &detailedError] (
                        Status _status, uint32_t _bytesWritten,
                        Status _status, uint32_t _bytesWritten,
                        const hidl_string& _detailedError) {
                        const hidl_string& _detailedError) {
@@ -1492,9 +1491,15 @@ status_t ATSParser::Stream::flushScrambled(SyncEvent *event) {


        ALOGV("[stream %d] descramble succeeded, %d bytes",
        ALOGV("[stream %d] descramble succeeded, %d bytes",
                mElementaryPID, bytesWritten);
                mElementaryPID, bytesWritten);
        memcpy(mBuffer->data(), mDescrambledBuffer->data(), descrambleBytes);

        // Set descrambleBytes to the returned result.
        // Note that this might be smaller than the total length of input data.
        // (eg. when we're descrambling the PES header portion of a secure stream,
        // the plugin might cut it off right after the PES header.)
        descrambleBytes = bytesWritten;
    }
    }


    sp<ABuffer> buffer;
    if (mQueue->isScrambled()) {
    if (mQueue->isScrambled()) {
        // Queue subSample info for scrambled queue
        // Queue subSample info for scrambled queue
        sp<ABuffer> clearSizesBuffer = new ABuffer(mSubSamples.size() * 4);
        sp<ABuffer> clearSizesBuffer = new ABuffer(mSubSamples.size() * 4);
@@ -1506,8 +1511,7 @@ status_t ATSParser::Stream::flushScrambled(SyncEvent *event) {
        for (auto it = mSubSamples.begin();
        for (auto it = mSubSamples.begin();
                it != mSubSamples.end(); it++, i++) {
                it != mSubSamples.end(); it++, i++) {
            if ((it->transport_scrambling_mode == 0
            if ((it->transport_scrambling_mode == 0
                    && pesScramblingControl == 0)
                    && pesScramblingControl == 0)) {
                    || i < descrambleSubSamples) {
                clearSizePtr[i] = it->subSampleSize;
                clearSizePtr[i] = it->subSampleSize;
                encSizePtr[i] = 0;
                encSizePtr[i] = 0;
            } else {
            } else {
@@ -1516,14 +1520,26 @@ status_t ATSParser::Stream::flushScrambled(SyncEvent *event) {
            }
            }
            isSync |= it->random_access_indicator;
            isSync |= it->random_access_indicator;
        }
        }

        // If scrambled at PES-level, PES header is in the clear
        if (pesScramblingControl != 0) {
            clearSizePtr[0] = pesOffset;
            encSizePtr[0] -= pesOffset;
        }
        // Pass the original TS subsample size now. The PES header adjust
        // Pass the original TS subsample size now. The PES header adjust
        // will be applied when the scrambled AU is dequeued.
        // will be applied when the scrambled AU is dequeued.
        mQueue->appendScrambledData(
        mQueue->appendScrambledData(
                mBuffer->data(), mBuffer->size(), sctrl,
                mBuffer->data(), mBuffer->size(), sctrl,
                isSync, clearSizesBuffer, encSizesBuffer);
                isSync, clearSizesBuffer, encSizesBuffer);

        buffer = mDescrambledBuffer;
    } else {
        memcpy(mBuffer->data(), mDescrambledBuffer->data(), descrambleBytes);

        buffer = mBuffer;
    }
    }


    ABitReader br(mBuffer->data(), mBuffer->size());
    ABitReader br(buffer->data(), buffer->size());
    status_t err = parsePES(&br, event);
    status_t err = parsePES(&br, event);


    if (err != OK) {
    if (err != OK) {
+8 −0
Original line number Original line Diff line number Diff line
@@ -226,6 +226,7 @@ status_t AnotherPacketSource::read(
        int32_t cryptoMode;
        int32_t cryptoMode;
        if (buffer->meta()->findInt32("cryptoMode", &cryptoMode)) {
        if (buffer->meta()->findInt32("cryptoMode", &cryptoMode)) {
            int32_t cryptoKey;
            int32_t cryptoKey;
            int32_t pesOffset;
            sp<ABuffer> clearBytesBuffer, encBytesBuffer;
            sp<ABuffer> clearBytesBuffer, encBytesBuffer;


            CHECK(buffer->meta()->findInt32("cryptoKey", &cryptoKey));
            CHECK(buffer->meta()->findInt32("cryptoKey", &cryptoKey));
@@ -233,6 +234,8 @@ status_t AnotherPacketSource::read(
                    && clearBytesBuffer != NULL);
                    && clearBytesBuffer != NULL);
            CHECK(buffer->meta()->findBuffer("encBytes", &encBytesBuffer)
            CHECK(buffer->meta()->findBuffer("encBytes", &encBytesBuffer)
                    && encBytesBuffer != NULL);
                    && encBytesBuffer != NULL);
            CHECK(buffer->meta()->findInt32("pesOffset", &pesOffset)
                    && (pesOffset >= 0) && (pesOffset < 65536));


            bufmeta.setInt32(kKeyCryptoMode, cryptoMode);
            bufmeta.setInt32(kKeyCryptoMode, cryptoMode);


@@ -240,6 +243,11 @@ status_t AnotherPacketSource::read(
            bufmeta.setData(kKeyCryptoIV, 0, array, 16);
            bufmeta.setData(kKeyCryptoIV, 0, array, 16);


            array[0] = (uint8_t) (cryptoKey & 0xff);
            array[0] = (uint8_t) (cryptoKey & 0xff);
            // array[1] contains PES header flag, which we don't use.
            // array[2~3] contain the PES offset.
            array[2] = (uint8_t) (pesOffset & 0xff);
            array[3] = (uint8_t) ((pesOffset >> 8) & 0xff);

            bufmeta.setData(kKeyCryptoKey, 0, array, 16);
            bufmeta.setData(kKeyCryptoKey, 0, array, 16);


            bufmeta.setData(kKeyPlainSizes, 0,
            bufmeta.setData(kKeyPlainSizes, 0,
+3 −18
Original line number Original line Diff line number Diff line
@@ -691,25 +691,9 @@ sp<ABuffer> ElementaryStreamQueue::dequeueScrambledAccessUnit() {
        return NULL;
        return NULL;
    }
    }


    // skip the PES header, and copy the rest into scrambled access unit
    // copy into scrambled access unit
    sp<ABuffer> scrambledAccessUnit = ABuffer::CreateAsCopy(
    sp<ABuffer> scrambledAccessUnit = ABuffer::CreateAsCopy(
            mScrambledBuffer->data() + pesOffset,
            mScrambledBuffer->data(), scrambledLength);
            scrambledLength - pesOffset);

    // fix up first sample size after skipping the PES header
    if (pesOffset > 0) {
        int32_t &firstClearSize = *(int32_t*)clearSizes->data();
        int32_t &firstEncSize = *(int32_t*)encSizes->data();
        // Cut away the PES header
        if (firstClearSize >= pesOffset) {
            // This is for TS-level scrambling, we descrambled the first
            // (or it was clear to begin with)
            firstClearSize -= pesOffset;
        } else if (firstEncSize >= pesOffset) {
            // This can only be PES-level scrambling
            firstEncSize -= pesOffset;
        }
    }


    scrambledAccessUnit->meta()->setInt64("timeUs", timeUs);
    scrambledAccessUnit->meta()->setInt64("timeUs", timeUs);
    if (isSync) {
    if (isSync) {
@@ -723,6 +707,7 @@ sp<ABuffer> ElementaryStreamQueue::dequeueScrambledAccessUnit() {
    scrambledAccessUnit->meta()->setInt32("cryptoKey", keyId);
    scrambledAccessUnit->meta()->setInt32("cryptoKey", keyId);
    scrambledAccessUnit->meta()->setBuffer("clearBytes", clearSizes);
    scrambledAccessUnit->meta()->setBuffer("clearBytes", clearSizes);
    scrambledAccessUnit->meta()->setBuffer("encBytes", encSizes);
    scrambledAccessUnit->meta()->setBuffer("encBytes", encSizes);
    scrambledAccessUnit->meta()->setInt32("pesOffset", pesOffset);


    memmove(mScrambledBuffer->data(),
    memmove(mScrambledBuffer->data(),
            mScrambledBuffer->data() + scrambledLength,
            mScrambledBuffer->data() + scrambledLength,