diff --git a/components/VideoFramePool.cpp b/components/VideoFramePool.cpp
index 665ff737e96b1f0f2c11c0c3dd6fbecb011f8de7..05e22a625cf935031214c844b083c2c6fc705745 100644
--- a/components/VideoFramePool.cpp
+++ b/components/VideoFramePool.cpp
@@ -176,28 +176,41 @@ void VideoFramePool::getVideoFrameTask() {
     // Variables used to exponential backoff retry when buffer fetching times out.
     constexpr size_t kFetchRetryDelayInit = 64;    // Initial delay: 64us
     constexpr size_t kFetchRetryDelayMax = 16384;  // Max delay: 16ms (1 frame at 60fps)
+    constexpr size_t kFenceWaitTimeoutNs = 16000000;  // 16ms (1 frame at 60fps)
     static size_t sNumRetries = 0;
     static size_t sDelay = kFetchRetryDelayInit;
 
+    C2Fence fence;
     std::shared_ptr<C2GraphicBlock> block;
-    c2_status_t err = mBlockPool->fetchGraphicBlock(
-            mSize.width, mSize.height, static_cast<uint32_t>(mPixelFormat), mMemoryUsage, &block);
-    if (err == C2_TIMED_OUT || err == C2_BLOCKING) {
-        if (setNotifyBlockAvailableCb(*mBlockPool,
-                                      ::base::BindOnce(&VideoFramePool::getVideoFrameTaskThunk,
-                                                       mFetchTaskRunner, mFetchWeakThis))) {
-            ALOGV("%s(): fetchGraphicBlock() timeout, waiting for block available.", __func__);
-        } else {
-            ALOGV("%s(): fetchGraphicBlock() timeout, waiting %zuus (%zu retry)", __func__, sDelay,
-                  sNumRetries + 1);
-            mFetchTaskRunner->PostDelayedTask(
-                    FROM_HERE, ::base::BindOnce(&VideoFramePool::getVideoFrameTask, mFetchWeakThis),
-                    ::base::TimeDelta::FromMicroseconds(sDelay));
-
-            sDelay = std::min(sDelay * 2, kFetchRetryDelayMax);  // Exponential backoff
-            sNumRetries++;
+    c2_status_t err = mBlockPool->fetchGraphicBlock(mSize.width, mSize.height,
+                                                    static_cast<uint32_t>(mPixelFormat),
+                                                    mMemoryUsage, &block, &fence);
+    if (err == C2_BLOCKING) {
+        err = fence.wait(kFenceWaitTimeoutNs);
+        if (err == C2_OK) {
+            ALOGV("%s(): fence wait succeded, retrying now", __func__);
+            mFetchTaskRunner->PostTask(
+                    FROM_HERE,
+                    ::base::BindOnce(&VideoFramePool::getVideoFrameTask, mFetchWeakThis));
+            return;
         }
+        ALOGV("%s(): fence wait unsucessful err=%d", __func__, err);
+    } else if (err == C2_OMITTED) {
+        // Fenced version is not supported, try legacy version.
+        err = mBlockPool->fetchGraphicBlock(mSize.width, mSize.height,
+                                            static_cast<uint32_t>(mPixelFormat), mMemoryUsage,
+                                            &block);
+    }
 
+    if (err == C2_TIMED_OUT || err == C2_BLOCKING) {
+        ALOGV("%s(): fetchGraphicBlock() timeout, waiting %zuus (%zu retry)", __func__, sDelay,
+              sNumRetries + 1);
+        mFetchTaskRunner->PostDelayedTask(
+                FROM_HERE, ::base::BindOnce(&VideoFramePool::getVideoFrameTask, mFetchWeakThis),
+                ::base::TimeDelta::FromMicroseconds(sDelay));
+
+        sDelay = std::min(sDelay * 2, kFetchRetryDelayMax);  // Exponential backoff
+        sNumRetries++;
         return;
     }
 
@@ -205,20 +218,28 @@ void VideoFramePool::getVideoFrameTask() {
     sNumRetries = 0;
     sDelay = kFetchRetryDelayInit;
 
+    if (err != C2_OK) {
+        ALOGE("%s(): Failed to fetch block, err=%d", __func__, err);
+        return;
+    }
+
+    ALOG_ASSERT(block != nullptr);
+    std::unique_ptr<VideoFrame> frame = VideoFrame::Create(std::move(block));
     std::optional<FrameWithBlockId> frameWithBlockId;
-    if (err == C2_OK) {
-        ALOG_ASSERT(block != nullptr);
-        std::optional<uint32_t> bufferId = getBufferIdFromGraphicBlock(*mBlockPool, *block);
-        std::unique_ptr<VideoFrame> frame = VideoFrame::Create(std::move(block));
+    std::optional<uint32_t> bufferId;
+
+    if (bufferId && frame) {
+        bufferId = getBufferIdFromGraphicBlock(*mBlockPool, *block);
+
+        if (bufferId) {
+            ALOGV("%s(): Got buffer with id = %u", __func__, *bufferId);
+        }
+
         // Only pass the frame + id pair if both have successfully been obtained.
         // Otherwise exit the loop so a nullopt is passed to the client.
-        if (bufferId && frame) {
-            frameWithBlockId = std::make_pair(std::move(frame), *bufferId);
-        } else {
-            ALOGE("%s(): Failed to generate VideoFrame or get the buffer id.", __func__);
-        }
+        frameWithBlockId = std::make_pair(std::move(frame), *bufferId);
     } else {
-        ALOGE("%s(): Failed to fetch block, err=%d", __func__, err);
+        ALOGE("%s(): Failed to generate VideoFrame or get the buffer id.", __func__);
     }
 
     mClientTaskRunner->PostTask(