Loading media/libstagefright/ACodecBufferChannel.cpp +15 −2 Original line number Original line Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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, Loading @@ -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) { Loading @@ -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(); Loading media/libstagefright/mpeg2ts/ATSParser.cpp +26 −10 Original line number Original line Diff line number Diff line Loading @@ -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); Loading @@ -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; } } Loading @@ -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) { Loading @@ -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); Loading @@ -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 { Loading @@ -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) { Loading media/libstagefright/mpeg2ts/AnotherPacketSource.cpp +8 −0 Original line number Original line Diff line number Diff line Loading @@ -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)); Loading @@ -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); Loading @@ -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, Loading media/libstagefright/mpeg2ts/ESQueue.cpp +3 −18 Original line number Original line Diff line number Diff line Loading @@ -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) { Loading @@ -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, Loading Loading
media/libstagefright/ACodecBufferChannel.cpp +15 −2 Original line number Original line Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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, Loading @@ -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) { Loading @@ -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(); Loading
media/libstagefright/mpeg2ts/ATSParser.cpp +26 −10 Original line number Original line Diff line number Diff line Loading @@ -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); Loading @@ -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; } } Loading @@ -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) { Loading @@ -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); Loading @@ -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 { Loading @@ -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) { Loading
media/libstagefright/mpeg2ts/AnotherPacketSource.cpp +8 −0 Original line number Original line Diff line number Diff line Loading @@ -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)); Loading @@ -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); Loading @@ -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, Loading
media/libstagefright/mpeg2ts/ESQueue.cpp +3 −18 Original line number Original line Diff line number Diff line Loading @@ -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) { Loading @@ -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, Loading