V4L2Decoder: do not check for DRC for secure codec
It's not possible to access the frame data if the secure codec is used.
An attempt to map() such data will result in an error, and attempt to
wait for the DRC will cause a nullptr dereference.
This patch adds a workaround, which skips the DRC verification if the
secure codec is used.
Bug: 280853786
Bug: 274864105
Test: GtsExoPlayerTestCases
Change-Id: I5b9d990c87b8afef2817f6bb9b9d8afb42017ca9
(cherry picked from commit 8fce6a632586b49aa23b14235363dca0f1fe0a7c)
diff --git a/v4l2/V4L2DecodeComponent.cpp b/v4l2/V4L2DecodeComponent.cpp
index e13a72c..284b094 100644
--- a/v4l2/V4L2DecodeComponent.cpp
+++ b/v4l2/V4L2DecodeComponent.cpp
@@ -106,7 +106,7 @@
::base::Unretained(this)),
::base::BindRepeating(&V4L2DecodeComponent::reportError,
::base::Unretained(this), C2_CORRUPTED),
- mDecoderTaskRunner);
+ mDecoderTaskRunner, mIsSecure);
if (!mDecoder) {
ALOGE("Failed to create V4L2Decoder for %s", VideoCodecToString(*codec));
return;
@@ -121,4 +121,4 @@
*status = C2_OK;
}
-} // namespace android
\ No newline at end of file
+} // namespace android
diff --git a/v4l2/V4L2Decoder.cpp b/v4l2/V4L2Decoder.cpp
index e10a1ef..d0d862d 100644
--- a/v4l2/V4L2Decoder.cpp
+++ b/v4l2/V4L2Decoder.cpp
@@ -67,11 +67,11 @@
std::unique_ptr<VideoDecoder> V4L2Decoder::Create(
uint32_t debugStreamId, const VideoCodec& codec, const size_t inputBufferSize,
const size_t minNumOutputBuffers, GetPoolCB getPoolCb, OutputCB outputCb, ErrorCB errorCb,
- scoped_refptr<::base::SequencedTaskRunner> taskRunner) {
+ scoped_refptr<::base::SequencedTaskRunner> taskRunner, bool isSecure) {
std::unique_ptr<V4L2Decoder> decoder =
::base::WrapUnique<V4L2Decoder>(new V4L2Decoder(debugStreamId, taskRunner));
if (!decoder->start(codec, inputBufferSize, minNumOutputBuffers, std::move(getPoolCb),
- std::move(outputCb), std::move(errorCb))) {
+ std::move(outputCb), std::move(errorCb), isSecure)) {
return nullptr;
}
return decoder;
@@ -113,7 +113,7 @@
bool V4L2Decoder::start(const VideoCodec& codec, const size_t inputBufferSize,
const size_t minNumOutputBuffers, GetPoolCB getPoolCb, OutputCB outputCb,
- ErrorCB errorCb) {
+ ErrorCB errorCb, bool isSecure) {
ATRACE_CALL();
ALOGV("%s(codec=%s, inputBufferSize=%zu, minNumOutputBuffers=%zu)", __func__,
VideoCodecToString(codec), inputBufferSize, minNumOutputBuffers);
@@ -124,6 +124,7 @@
mOutputCb = std::move(outputCb);
mErrorCb = std::move(errorCb);
mCodec = codec;
+ mIsSecure = isSecure;
if (mState == State::Error) {
ALOGE("Ignore due to error state.");
@@ -359,7 +360,11 @@
setState(State::Decoding);
}
- if (mInitialEosBuffer && !mPendingDRC) mPendingDRC = waitForDRC(buffer->dmabuf, mCodec);
+ // To determine if the DRC is pending, the access to the frame data is
+ // required. It's not possible to access the frame directly for the secure
+ // playback, so this check must be skipped. b/279834186
+ if (!mIsSecure && mInitialEosBuffer && !mPendingDRC)
+ mPendingDRC = waitForDRC(buffer->dmabuf, mCodec);
mDecodeRequests.push(DecodeRequest(std::move(buffer), std::move(decodeCb)));
pumpDecodeRequest();
diff --git a/v4l2/include/v4l2_codec2/v4l2/V4L2Decoder.h b/v4l2/include/v4l2_codec2/v4l2/V4L2Decoder.h
index 839574f..e569c1c 100644
--- a/v4l2/include/v4l2_codec2/v4l2/V4L2Decoder.h
+++ b/v4l2/include/v4l2_codec2/v4l2/V4L2Decoder.h
@@ -40,7 +40,7 @@
static std::unique_ptr<VideoDecoder> Create(
uint32_t debugStreamId, const VideoCodec& codec, const size_t inputBufferSize,
const size_t minNumOutputBuffers, GetPoolCB getPoolCB, OutputCB outputCb,
- ErrorCB errorCb, scoped_refptr<::base::SequencedTaskRunner> taskRunner);
+ ErrorCB errorCb, scoped_refptr<::base::SequencedTaskRunner> taskRunner, bool isSecure);
~V4L2Decoder() override;
void decode(std::unique_ptr<ConstBitstreamBuffer> buffer, DecodeCB decodeCb) override;
@@ -71,7 +71,7 @@
V4L2Decoder(uint32_t debugStreamId, scoped_refptr<::base::SequencedTaskRunner> taskRunner);
bool start(const VideoCodec& codec, const size_t inputBufferSize,
const size_t minNumOutputBuffers, GetPoolCB getPoolCb, OutputCB outputCb,
- ErrorCB errorCb);
+ ErrorCB errorCb, bool isSecure);
bool setupInputFormat(const uint32_t inputPixelFormat, const size_t inputBufferSize);
// Sets minimal resolution and allocates minimal amount of output buffers for
@@ -115,6 +115,10 @@
std::map<int32_t, DecodeCB> mPendingDecodeCbs;
// Marks that we need to wait for DRC before drain can complete.
bool mPendingDRC = false;
+ // Holds information about secure playback, which won't allow decoder to
+ // access frames in order to provide extra meta information (like checking
+ // for pending DRC).
+ bool mIsSecure;
VideoCodec mCodec;
// Tracks the last DMA buffer ID which was used for a given V4L2 input