diff --git a/v4l2/V4L2DecodeComponent.cpp b/v4l2/V4L2DecodeComponent.cpp
index e13a72ccc6062ee7b8b303e1c3ed8b80b41f085d..284b094bdaad3f237adc51a2462e4fe8e9b09285 100644
--- a/v4l2/V4L2DecodeComponent.cpp
+++ b/v4l2/V4L2DecodeComponent.cpp
@@ -106,7 +106,7 @@ void V4L2DecodeComponent::startTask(c2_status_t* status, ::base::WaitableEvent*
                                                          ::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 @@ void V4L2DecodeComponent::startTask(c2_status_t* status, ::base::WaitableEvent*
     *status = C2_OK;
 }
 
-}  // namespace android
\ No newline at end of file
+}  // namespace android
diff --git a/v4l2/V4L2Decoder.cpp b/v4l2/V4L2Decoder.cpp
index e10a1efa8b14a7f986957c45cafb2ed9510a300f..d0d862df6aff36de5969e60bc69f05422d1e63f7 100644
--- a/v4l2/V4L2Decoder.cpp
+++ b/v4l2/V4L2Decoder.cpp
@@ -67,11 +67,11 @@ bool waitForDRC(const C2ConstLinearBlock& input, std::optional<VideoCodec> codec
 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 @@ V4L2Decoder::~V4L2Decoder() {
 
 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 @@ bool V4L2Decoder::start(const VideoCodec& codec, const size_t inputBufferSize,
     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 @@ void V4L2Decoder::decode(std::unique_ptr<ConstBitstreamBuffer> buffer, DecodeCB
         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 839574f291afbbde3b5621f132ddc85cea618429..e569c1c5d37b5ded75f987f4bcef1957fb6ecaf6 100644
--- a/v4l2/include/v4l2_codec2/v4l2/V4L2Decoder.h
+++ b/v4l2/include/v4l2_codec2/v4l2/V4L2Decoder.h
@@ -40,7 +40,7 @@ public:
     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 @@ private:
     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 @@ private:
     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