media.c2 aidl: add C2AidlNode

Bug: 322870482
Test: m libsfplugin_ccodec
Merged-In: I717de624c3c10fb2c84456e110b7513d078fd6a0
Change-Id: I717de624c3c10fb2c84456e110b7513d078fd6a0
diff --git a/media/codec2/sfplugin/C2NodeImpl.cpp b/media/codec2/sfplugin/C2NodeImpl.cpp
index 778686c..6f53e0f 100644
--- a/media/codec2/sfplugin/C2NodeImpl.cpp
+++ b/media/codec2/sfplugin/C2NodeImpl.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright 2018, The Android Open Source Project
+ * Copyright 2024, The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,30 +14,22 @@
  * limitations under the License.
  */
 
-#ifdef __LP64__
-#define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
-#endif
-
 //#define LOG_NDEBUG 0
-#define LOG_TAG "C2OMXNode"
+#define LOG_TAG "C2NodeImpl"
 #include <log/log.h>
 
 #include <C2AllocatorGralloc.h>
 #include <C2BlockInternal.h>
 #include <C2Component.h>
 #include <C2Config.h>
+#include <C2Debug.h>
 #include <C2PlatformSupport.h>
 
-#include <OMX_Component.h>
-#include <OMX_Index.h>
-#include <OMX_IndexExt.h>
-
 #include <android/fdsan.h>
 #include <media/stagefright/foundation/ColorUtils.h>
-#include <media/stagefright/omx/OMXUtils.h>
-#include <media/stagefright/MediaErrors.h>
 #include <ui/Fence.h>
 #include <ui/GraphicBuffer.h>
+#include <utils/Errors.h>
 #include <utils/Thread.h>
 
 #include "utils/Codec2Mapper.h"
@@ -46,9 +38,12 @@
 
 namespace android {
 
-namespace {
+using ::aidl::android::media::IAidlBufferSource;
+using ::aidl::android::media::IAidlNode;
 
-constexpr OMX_U32 kPortIndexInput = 0;
+using ::android::media::BUFFERFLAG_EOS;
+
+namespace {
 
 class Buffer2D : public C2Buffer {
 public:
@@ -57,7 +52,7 @@
 
 }  // namespace
 
-class C2OMXNode::QueueThread : public Thread {
+class C2NodeImpl::QueueThread : public Thread {
 public:
     QueueThread() : Thread(false) {}
     ~QueueThread() override = default;
@@ -195,12 +190,12 @@
     Mutexed<Jobs> mJobs;
 };
 
-C2OMXNode::C2OMXNode(const std::shared_ptr<Codec2Client::Component> &comp)
+C2NodeImpl::C2NodeImpl(const std::shared_ptr<Codec2Client::Component> &comp, bool aidl)
     : mComp(comp), mFrameIndex(0), mWidth(0), mHeight(0), mUsage(0),
       mAdjustTimestampGapUs(0), mFirstInputFrame(true),
-      mQueueThread(new QueueThread) {
+      mQueueThread(new QueueThread), mAidlHal(aidl) {
     android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ALWAYS);
-    mQueueThread->run("C2OMXNode", PRIORITY_AUDIO);
+    mQueueThread->run("C2NodeImpl", PRIORITY_AUDIO);
 
     android_dataspace ds = HAL_DATASPACE_UNKNOWN;
     mDataspace.lock().set(ds);
@@ -208,224 +203,105 @@
     mPixelFormat.lock().set(pf);
 }
 
-status_t C2OMXNode::freeNode() {
+C2NodeImpl::~C2NodeImpl() {
+}
+
+status_t C2NodeImpl::freeNode() {
     mComp.reset();
     android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE);
     return mQueueThread->requestExitAndWait();
 }
 
-status_t C2OMXNode::sendCommand(OMX_COMMANDTYPE cmd, OMX_S32 param) {
-    if (cmd == OMX_CommandStateSet && param == OMX_StateLoaded) {
-        // Reset first input frame so if C2OMXNode is recycled, the timestamp does not become
-        // negative. This is a workaround for HW codecs that do not handle timestamp rollover.
-        mFirstInputFrame = true;
-    }
-    return ERROR_UNSUPPORTED;
+void C2NodeImpl::onFirstInputFrame() {
+    mFirstInputFrame = true;
 }
 
-status_t C2OMXNode::getParameter(OMX_INDEXTYPE index, void *params, size_t size) {
-    status_t err = ERROR_UNSUPPORTED;
-    switch ((uint32_t)index) {
-        case OMX_IndexParamConsumerUsageBits: {
-            OMX_U32 *usage = (OMX_U32 *)params;
-            *usage = mUsage;
-            err = OK;
-            break;
+void C2NodeImpl::getConsumerUsageBits(uint64_t *usage) {
+    *usage = mUsage;
+}
+
+void C2NodeImpl::getInputBufferParams(IAidlNode::InputBufferParams *params) {
+    params->bufferCountActual = 16;
+
+    // WORKAROUND: having more slots improve performance while consuming
+    // more memory. This is a temporary workaround to reduce memory for
+    // larger-than-4K scenario.
+    if (mWidth * mHeight > 4096 * 2340) {
+        std::shared_ptr<Codec2Client::Component> comp = mComp.lock();
+        C2PortActualDelayTuning::input inputDelay(0);
+        C2ActualPipelineDelayTuning pipelineDelay(0);
+        c2_status_t c2err = C2_NOT_FOUND;
+        if (comp) {
+            c2err = comp->query(
+                    {&inputDelay, &pipelineDelay}, {}, C2_DONT_BLOCK, nullptr);
         }
-        case OMX_IndexParamConsumerUsageBits64: {
-            OMX_U64 *usage = (OMX_U64 *)params;
-            *usage = mUsage;
-            err = OK;
-            break;
+        if (c2err == C2_OK || c2err == C2_BAD_INDEX) {
+            params->bufferCountActual = 4;
+            params->bufferCountActual += (inputDelay ? inputDelay.value : 0u);
+            params->bufferCountActual += (pipelineDelay ? pipelineDelay.value : 0u);
         }
-        case OMX_IndexParamPortDefinition: {
-            if (size < sizeof(OMX_PARAM_PORTDEFINITIONTYPE)) {
-                return BAD_VALUE;
-            }
-            OMX_PARAM_PORTDEFINITIONTYPE *pDef = (OMX_PARAM_PORTDEFINITIONTYPE *)params;
-            if (pDef->nPortIndex != kPortIndexInput) {
-                break;
-            }
-
-            pDef->nBufferCountActual = 16;
-
-            // WORKAROUND: having more slots improve performance while consuming
-            // more memory. This is a temporary workaround to reduce memory for
-            // larger-than-4K scenario.
-            if (mWidth * mHeight > 4096 * 2340) {
-                std::shared_ptr<Codec2Client::Component> comp = mComp.lock();
-                C2PortActualDelayTuning::input inputDelay(0);
-                C2ActualPipelineDelayTuning pipelineDelay(0);
-                c2_status_t c2err = C2_NOT_FOUND;
-                if (comp) {
-                    c2err = comp->query(
-                            {&inputDelay, &pipelineDelay}, {}, C2_DONT_BLOCK, nullptr);
-                }
-                if (c2err == C2_OK || c2err == C2_BAD_INDEX) {
-                    pDef->nBufferCountActual = 4;
-                    pDef->nBufferCountActual += (inputDelay ? inputDelay.value : 0u);
-                    pDef->nBufferCountActual += (pipelineDelay ? pipelineDelay.value : 0u);
-                }
-            }
-
-            pDef->eDomain = OMX_PortDomainVideo;
-            pDef->format.video.nFrameWidth = mWidth;
-            pDef->format.video.nFrameHeight = mHeight;
-            pDef->format.video.eColorFormat = OMX_COLOR_FormatAndroidOpaque;
-            err = OK;
-            break;
-        }
-        default:
-            break;
     }
-    return err;
+
+    params->frameWidth = mWidth;
+    params->frameHeight = mHeight;
 }
 
-status_t C2OMXNode::setParameter(OMX_INDEXTYPE index, const void *params, size_t size) {
-    if (params == NULL) {
-        return BAD_VALUE;
-    }
-    switch ((uint32_t)index) {
-        case OMX_IndexParamMaxFrameDurationForBitrateControl:
-            // handle max/fixed frame duration control
-            if (size != sizeof(OMX_PARAM_U32TYPE)) {
-                return BAD_VALUE;
-            }
-            // The incoming number is an int32_t contained in OMX_U32.
-            mAdjustTimestampGapUs = (int32_t)((OMX_PARAM_U32TYPE*)params)->nU32;
-            return OK;
-
-        case OMX_IndexParamConsumerUsageBits:
-            if (size != sizeof(OMX_U32)) {
-                return BAD_VALUE;
-            }
-            mUsage = *((OMX_U32 *)params);
-            return OK;
-
-        case OMX_IndexParamConsumerUsageBits64:
-            if (size != sizeof(OMX_U64)) {
-                return BAD_VALUE;
-            }
-            mUsage = *((OMX_U64 *)params);
-            return OK;
-    }
-    return ERROR_UNSUPPORTED;
+void C2NodeImpl::setConsumerUsageBits(uint64_t usage) {
+    mUsage = usage;
 }
 
-status_t C2OMXNode::getConfig(OMX_INDEXTYPE index, void *config, size_t size) {
-    (void)index;
-    (void)config;
-    (void)size;
-    return ERROR_UNSUPPORTED;
+void C2NodeImpl::setAdjustTimestampGapUs(int32_t gapUs) {
+    mAdjustTimestampGapUs = gapUs;
 }
 
-status_t C2OMXNode::setConfig(OMX_INDEXTYPE index, const void *config, size_t size) {
-    (void)index;
-    (void)config;
-    (void)size;
-    return ERROR_UNSUPPORTED;
-}
-
-status_t C2OMXNode::setPortMode(OMX_U32 portIndex, IOMX::PortMode mode) {
-    (void)portIndex;
-    (void)mode;
-    return ERROR_UNSUPPORTED;
-}
-
-status_t C2OMXNode::prepareForAdaptivePlayback(
-        OMX_U32 portIndex, OMX_BOOL enable,
-        OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight) {
-    (void)portIndex;
-    (void)enable;
-    (void)maxFrameWidth;
-    (void)maxFrameHeight;
-    return ERROR_UNSUPPORTED;
-}
-
-status_t C2OMXNode::configureVideoTunnelMode(
-        OMX_U32 portIndex, OMX_BOOL tunneled,
-        OMX_U32 audioHwSync, native_handle_t **sidebandHandle) {
-    (void)portIndex;
-    (void)tunneled;
-    (void)audioHwSync;
-    *sidebandHandle = nullptr;
-    return ERROR_UNSUPPORTED;
-}
-
-status_t C2OMXNode::getGraphicBufferUsage(OMX_U32 portIndex, OMX_U32* usage) {
-    (void)portIndex;
-    *usage = 0;
-    return ERROR_UNSUPPORTED;
-}
-
-status_t C2OMXNode::setInputSurface(const sp<IOMXBufferSource> &bufferSource) {
+status_t C2NodeImpl::setInputSurface(const sp<IOMXBufferSource> &bufferSource) {
     c2_status_t err = GetCodec2PlatformAllocatorStore()->fetchAllocator(
             C2PlatformAllocatorStore::GRALLOC,
             &mAllocator);
     if (err != OK) {
         return UNKNOWN_ERROR;
     }
+    CHECK(!mAidlHal);
     mBufferSource = bufferSource;
     return OK;
 }
 
-status_t C2OMXNode::allocateSecureBuffer(
-        OMX_U32 portIndex, size_t size, buffer_id *buffer,
-        void **bufferData, sp<NativeHandle> *nativeHandle) {
-    (void)portIndex;
-    (void)size;
-    (void)nativeHandle;
-    *buffer = 0;
-    *bufferData = nullptr;
-    return ERROR_UNSUPPORTED;
+status_t C2NodeImpl::setAidlInputSurface(
+        const std::shared_ptr<IAidlBufferSource> &aidlBufferSource) {
+    c2_status_t err = GetCodec2PlatformAllocatorStore()->fetchAllocator(
+            C2PlatformAllocatorStore::GRALLOC,
+            &mAllocator);
+    if (err != OK) {
+        return UNKNOWN_ERROR;
+    }
+    CHECK(mAidlHal);
+    mAidlBufferSource = aidlBufferSource;
+    return OK;
 }
 
-status_t C2OMXNode::useBuffer(
-        OMX_U32 portIndex, const OMXBuffer &omxBuf, buffer_id *buffer) {
-    (void)portIndex;
-    (void)omxBuf;
-    *buffer = 0;
-    return ERROR_UNSUPPORTED;
-}
-
-status_t C2OMXNode::freeBuffer(OMX_U32 portIndex, buffer_id buffer) {
-    (void)portIndex;
-    (void)buffer;
-    return ERROR_UNSUPPORTED;
-}
-
-status_t C2OMXNode::fillBuffer(
-        buffer_id buffer, const OMXBuffer &omxBuf, int fenceFd) {
-    (void)buffer;
-    (void)omxBuf;
-    (void)fenceFd;
-    return ERROR_UNSUPPORTED;
-}
-
-status_t C2OMXNode::emptyBuffer(
-        buffer_id buffer, const OMXBuffer &omxBuf,
-        OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) {
+status_t C2NodeImpl::submitBuffer(
+        uint32_t buffer, const sp<GraphicBuffer> &graphicBuffer,
+        uint32_t flags, int64_t timestamp, int fenceFd) {
     std::shared_ptr<Codec2Client::Component> comp = mComp.lock();
     if (!comp) {
         return NO_INIT;
     }
 
-    uint32_t c2Flags = (flags & OMX_BUFFERFLAG_EOS)
+    uint32_t c2Flags = (flags & BUFFERFLAG_EOS)
             ? C2FrameData::FLAG_END_OF_STREAM : 0;
     std::shared_ptr<C2GraphicBlock> block;
 
     android::base::unique_fd fd0, fd1;
     C2Handle *handle = nullptr;
-    if (omxBuf.mBufferType == OMXBuffer::kBufferTypeANWBuffer
-            && omxBuf.mGraphicBuffer != nullptr) {
+    if (graphicBuffer) {
         std::shared_ptr<C2GraphicAllocation> alloc;
         handle = WrapNativeCodec2GrallocHandle(
-                omxBuf.mGraphicBuffer->handle,
-                omxBuf.mGraphicBuffer->width,
-                omxBuf.mGraphicBuffer->height,
-                omxBuf.mGraphicBuffer->format,
-                omxBuf.mGraphicBuffer->usage,
-                omxBuf.mGraphicBuffer->stride);
+                graphicBuffer->handle,
+                graphicBuffer->width,
+                graphicBuffer->height,
+                graphicBuffer->format,
+                graphicBuffer->usage,
+                graphicBuffer->stride);
         if (handle != nullptr) {
             // unique_fd takes ownership of the fds, we'll get warning if these
             // fds get closed by somebody else. Onwership will be released before
@@ -444,7 +320,7 @@
             return UNKNOWN_ERROR;
         }
         block = _C2BlockFactory::CreateGraphicBlock(alloc);
-    } else if (!(flags & OMX_BUFFERFLAG_EOS)) {
+    } else if (!(flags & BUFFERFLAG_EOS)) {
         return BAD_VALUE;
     }
 
@@ -503,44 +379,42 @@
     return OK;
 }
 
-status_t C2OMXNode::getExtensionIndex(
-        const char *parameterName, OMX_INDEXTYPE *index) {
-    (void)parameterName;
-    *index = OMX_IndexMax;
-    return ERROR_UNSUPPORTED;
-}
-
-status_t C2OMXNode::dispatchMessage(const omx_message& msg) {
-    if (msg.type != omx_message::EVENT) {
-        return ERROR_UNSUPPORTED;
-    }
-    if (msg.u.event_data.event != OMX_EventDataSpaceChanged) {
-        return ERROR_UNSUPPORTED;
-    }
-    android_dataspace dataSpace = (android_dataspace)msg.u.event_data.data1;
-    uint32_t pixelFormat = msg.u.event_data.data3;
-
+status_t C2NodeImpl::onDataspaceChanged(uint32_t dataSpace, uint32_t pixelFormat) {
     ALOGD("dataspace changed to %#x pixel format: %#x", dataSpace, pixelFormat);
-    mQueueThread->setDataspace(dataSpace);
+    android_dataspace d = (android_dataspace)dataSpace;
+    mQueueThread->setDataspace(d);
 
-    mDataspace.lock().set(dataSpace);
+    mDataspace.lock().set(d);
     mPixelFormat.lock().set(pixelFormat);
     return OK;
 }
 
-sp<IOMXBufferSource> C2OMXNode::getSource() {
+sp<IOMXBufferSource> C2NodeImpl::getSource() {
+    CHECK(!mAidlHal);
     return mBufferSource;
 }
 
-void C2OMXNode::setFrameSize(uint32_t width, uint32_t height) {
+std::shared_ptr<IAidlBufferSource> C2NodeImpl::getAidlSource() {
+    CHECK(mAidlHal);
+    return mAidlBufferSource;
+}
+
+void C2NodeImpl::setFrameSize(uint32_t width, uint32_t height) {
     mWidth = width;
     mHeight = height;
 }
 
-void C2OMXNode::onInputBufferDone(c2_cntr64_t index) {
-    if (!mBufferSource) {
-        ALOGD("Buffer source not set (index=%llu)", index.peekull());
-        return;
+void C2NodeImpl::onInputBufferDone(c2_cntr64_t index) {
+    if (mAidlHal) {
+        if (!mAidlBufferSource) {
+            ALOGD("Buffer source not set (index=%llu)", index.peekull());
+            return;
+        }
+    } else {
+        if (!mBufferSource) {
+            ALOGD("Buffer source not set (index=%llu)", index.peekull());
+            return;
+        }
     }
 
     int32_t bufferId = 0;
@@ -554,18 +428,23 @@
         bufferId = it->second;
         (void)bufferIds->erase(it);
     }
-    (void)mBufferSource->onInputBufferEmptied(bufferId, -1);
+    if (mAidlHal) {
+        ::ndk::ScopedFileDescriptor nullFence;
+        (void)mAidlBufferSource->onInputBufferEmptied(bufferId, nullFence);
+    } else {
+        (void)mBufferSource->onInputBufferEmptied(bufferId, -1);
+    }
 }
 
-android_dataspace C2OMXNode::getDataspace() {
+android_dataspace C2NodeImpl::getDataspace() {
     return *mDataspace.lock();
 }
 
-uint32_t C2OMXNode::getPixelFormat() {
+uint32_t C2NodeImpl::getPixelFormat() {
     return *mPixelFormat.lock();
 }
 
-void C2OMXNode::setPriority(int priority) {
+void C2NodeImpl::setPriority(int priority) {
     mQueueThread->setPriority(priority);
 }