media c2.aidl: PersistentSurface related aidl defs & impls
Bug: 322870482
Test: m libstagefright_graphicbuffersource_aidl
Merged-In: I61aa0bcb82344430ca7e828624f3cfbf7d888af8
Change-Id: I61aa0bcb82344430ca7e828624f3cfbf7d888af8
diff --git a/media/module/aidlpersistentsurface/AidlGraphicBufferSource.cpp b/media/module/aidlpersistentsurface/AidlGraphicBufferSource.cpp
new file mode 100644
index 0000000..c208666
--- /dev/null
+++ b/media/module/aidlpersistentsurface/AidlGraphicBufferSource.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <inttypes.h>
+
+#define LOG_TAG "AidlGraphicBufferSource"
+//#define LOG_NDEBUG 0
+#include <utils/Log.h>
+
+#include <media/stagefright/bqhelper/ComponentWrapper.h>
+#include <media/stagefright/bqhelper/GraphicBufferSource.h>
+#include <media/stagefright/aidlpersistentsurface/AidlGraphicBufferSource.h>
+#include <media/stagefright/aidlpersistentsurface/C2NodeDef.h>
+
+namespace android::media {
+
+namespace {
+
+class AidlComponentWrapper : public ComponentWrapper {
+public:
+ explicit AidlComponentWrapper(const sp<IAidlNodeWrapper> &node)
+ : mAidlNode(node) {}
+ virtual ~AidlComponentWrapper() = default;
+
+ status_t submitBuffer(
+ int32_t bufferId, const sp<GraphicBuffer> &buffer,
+ int64_t timestamp, int fenceFd) override {
+ return mAidlNode->submitBuffer(
+ bufferId, BUFFERFLAG_ENDOFFRAME, buffer, timestamp, fenceFd);
+ }
+
+ status_t submitEos(int32_t bufferId) override {
+ return mAidlNode->submitBuffer(
+ bufferId, BUFFERFLAG_ENDOFFRAME | BUFFERFLAG_EOS);
+ }
+
+ void dispatchDataSpaceChanged(
+ int32_t dataSpace, int32_t aspects, int32_t pixelFormat) override {
+ mAidlNode->dispatchDataSpaceChanged(dataSpace, aspects, pixelFormat);
+ }
+
+private:
+ sp<IAidlNodeWrapper> mAidlNode;
+
+ DISALLOW_EVIL_CONSTRUCTORS(AidlComponentWrapper);
+};
+
+} // namespace
+
+::ndk::ScopedAStatus AidlGraphicBufferSource::onStart() {
+ status_t err = start();
+ return (OK == err) ? ::ndk::ScopedAStatus::ok() :
+ ::ndk::ScopedAStatus::fromServiceSpecificError(err);
+}
+
+::ndk::ScopedAStatus AidlGraphicBufferSource::onStop() {
+ status_t err = stop();
+ return (OK == err) ? ::ndk::ScopedAStatus::ok() :
+ ::ndk::ScopedAStatus::fromServiceSpecificError(err);
+}
+
+::ndk::ScopedAStatus AidlGraphicBufferSource::onRelease(){
+ status_t err = release();
+ return (OK == err) ? ::ndk::ScopedAStatus::ok() :
+ ::ndk::ScopedAStatus::fromServiceSpecificError(err);
+}
+
+status_t AidlGraphicBufferSource::configure(
+ const sp<IAidlNodeWrapper>& aidlNode,
+ int32_t dataSpace,
+ int32_t bufferCount,
+ uint32_t frameWidth,
+ uint32_t frameHeight,
+ uint64_t consumerUsage) {
+ if (aidlNode == NULL) {
+ return BAD_VALUE;
+ }
+
+ return GraphicBufferSource::configure(
+ new AidlComponentWrapper(aidlNode), dataSpace, bufferCount,
+ frameWidth, frameHeight, consumerUsage);
+}
+
+} // namespace android::media
diff --git a/media/module/aidlpersistentsurface/Android.bp b/media/module/aidlpersistentsurface/Android.bp
new file mode 100644
index 0000000..5c1a010
--- /dev/null
+++ b/media/module/aidlpersistentsurface/Android.bp
@@ -0,0 +1,69 @@
+aidl_interface {
+ name: "graphicbuffersource-aidl",
+ unstable: true,
+ local_include_dir: "aidl",
+ min_sdk_version: "29",
+ srcs: [
+ "aidl/android/media/AidlColorAspects.aidl",
+ "aidl/android/media/IAidlGraphicBufferSource.aidl",
+ "aidl/android/media/IAidlBufferSource.aidl",
+ "aidl/android/media/IAidlNode.aidl",
+ ],
+ headers: [
+ "HardwareBuffer_aidl",
+ ],
+ imports: [
+ "android.hardware.graphics.common-V5",
+ ],
+ include_dirs: [
+ "frameworks/native/aidl/gui",
+ ],
+ backend: {
+ cpp: {
+ enabled: false,
+ },
+ java: {
+ enabled: false,
+ },
+ ndk: {
+ enabled: true,
+ additional_shared_libraries: [
+ "libnativewindow",
+ ],
+ },
+ rust: {
+ // No users, and no rust implementation of android.os.Surface yet
+ enabled: false,
+ },
+ },
+}
+
+cc_library_shared {
+ name: "libstagefright_graphicbuffersource_aidl",
+ min_sdk_version: "29",
+ srcs: [
+ "AidlGraphicBufferSource.cpp",
+ "wrapper/WAidlGraphicBufferSource.cpp",
+ ],
+ export_include_dirs: [
+ "include",
+ ],
+ header_libs: [
+ "media_plugin_headers",
+ ],
+
+ export_header_lib_headers: [
+ "media_plugin_headers",
+ ],
+ shared_libs: [
+ "android.hardware.graphics.common-V5-ndk",
+ "graphicbuffersource-aidl-ndk",
+ "libbinder_ndk",
+ "libcutils",
+ "libgui",
+ "liblog",
+ "libnativewindow",
+ "libstagefright_bufferqueue_helper",
+ "libutils",
+ ],
+}
diff --git a/media/module/aidlpersistentsurface/aidl/android/media/AidlColorAspects.aidl b/media/module/aidlpersistentsurface/aidl/android/media/AidlColorAspects.aidl
new file mode 100644
index 0000000..4edd6ce
--- /dev/null
+++ b/media/module/aidlpersistentsurface/aidl/android/media/AidlColorAspects.aidl
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media;
+
+/**
+ * Ref: frameworks/native/include/media/hardware/VideoAPI.h
+ *
+ * Framework defined color aspects. These are based mainly on ISO 23001-8 spec. As this standard
+ * continues to evolve, new values may be defined in the future. Use OTHER for these future values
+ * as well as for values not listed here, as those are not supported by the framework.
+ */
+parcelable AidlColorAspects {
+ @Backing(type="int")
+ enum Range {
+ UNSPECIFIED, // Unspecified
+ FULL, // Full range
+ LIMITED, // Limited range (if defined), or not full range
+
+ OTHER = 0xff, // Not one of the above values
+ }
+
+ // Color primaries
+ @Backing(type="int")
+ enum Primaries {
+ UNSPECIFIED, // Unspecified
+ BT709_5, // Rec.ITU-R BT.709-5 or equivalent
+ BT470_6M, // Rec.ITU-R BT.470-6 System M or equivalent
+ BT601_6_625, // Rec.ITU-R BT.601-6 625 or equivalent
+ BT601_6_525, // Rec.ITU-R BT.601-6 525 or equivalent
+ GENERIC_FILM, // Generic Film
+ BT2020, // Rec.ITU-R BT.2020 or equivalent
+
+ OTHER = 0xff, // Not one of the above values
+ }
+
+ // Transfer characteristics
+ @Backing(type="int")
+ enum Transfer {
+ UNSPECIFIED, // Unspecified
+ LINEAR, // Linear transfer characteristics
+ SRGB, // sRGB or equivalent
+ SMPTE170M, // SMPTE 170M or equivalent (e.g. BT.601/709/2020)
+ GAMMA22, // Assumed display gamma 2.2
+ GAMMA28, // Assumed display gamma 2.8
+ ST2084, // SMPTE ST 2084 for 10/12/14/16 bit systems
+ HLG, // ARIB STD-B67 hybrid-log-gamma
+
+ // values unlikely to be required by Android follow here
+ SMPTE240M = 0x40, // SMPTE 240M
+ XVYCC, // IEC 61966-2-4
+ BT1361, // Rec.ITU-R BT.1361 extended gamut
+ ST428, // SMPTE ST 428-1
+
+ OTHER = 0xff, // Not one of the above values
+ }
+
+ // YUV <-> RGB conversion
+ @Backing(type="int")
+ enum MatrixCoeffs {
+ UNSPECIFIED, // Unspecified
+ BT709_5, // Rec.ITU-R BT.709-5 or equivalent
+ BT470_6M, // KR=0.30, KB=0.11 or equivalent
+ BT601_6, // Rec.ITU-R BT.601-6 625 or equivalent
+ SMPTE240M, // SMPTE 240M or equivalent
+ BT2020, // Rec.ITU-R BT.2020 non-constant luminance
+ BT2020CONSTANT, // Rec.ITU-R BT.2020 constant luminance
+
+ OTHER = 0xff, // Not one of the above values
+ }
+
+ Range range;
+ Primaries primaries;
+ Transfer transfer;
+ MatrixCoeffs matrixCoeffs;
+}
diff --git a/media/module/aidlpersistentsurface/aidl/android/media/IAidlBufferSource.aidl b/media/module/aidlpersistentsurface/aidl/android/media/IAidlBufferSource.aidl
new file mode 100644
index 0000000..0679e41
--- /dev/null
+++ b/media/module/aidlpersistentsurface/aidl/android/media/IAidlBufferSource.aidl
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media;
+
+import android.os.ParcelFileDescriptor;
+
+/**
+ * Binder interface for controlling and handling IAidlGraphicBufferSource
+ * from the process which owns IAidlNode.
+ *
+ * In order to support Persistent InputSurface and/or MediaRecorder
+ */
+interface IAidlBufferSource {
+ /**
+ * This is called when IAidlGraphicBufferSource can start handing buffers.
+ * If we already have buffers of data sitting in the BufferQueue,
+ * this will send them to the codec.
+ */
+ void onStart();
+
+ /**
+ * This is called when IAidlGraphicBufferSource indicaters that
+ * the codec is meant to return all buffers back to the client for them
+ * to be freed. Do NOT submit any more buffers to the component.
+ */
+ void onStop();
+
+ /**
+ * This is called when IAidlGraphicBufferSource indicates that
+ * we are shutting down.
+ */
+ void onRelease();
+
+ /**
+ * A "codec buffer", i.e. a buffer that can be used to pass data into
+ * the encoder, has been allocated.
+ */
+ void onInputBufferAdded(int bufferID);
+
+ /**
+ * Called from OnEmptyBufferDone. If we have a BQ buffer available,
+ * fill it with a new frame of data; otherwise, just mark it as available.
+ *
+ * fence contains the fence's fd that the callee should wait on before
+ * using the buffer (or pass on to the user of the buffer, if the user supports
+ * fences). Callee takes ownership of the fence fd even if it fails.
+ */
+ void onInputBufferEmptied(int bufferID, in @nullable ParcelFileDescriptor fence);
+}
+
diff --git a/media/module/aidlpersistentsurface/aidl/android/media/IAidlGraphicBufferSource.aidl b/media/module/aidlpersistentsurface/aidl/android/media/IAidlGraphicBufferSource.aidl
new file mode 100644
index 0000000..6642e89
--- /dev/null
+++ b/media/module/aidlpersistentsurface/aidl/android/media/IAidlGraphicBufferSource.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media;
+
+import android.hardware.graphics.common.Dataspace;
+import android.media.AidlColorAspects;
+import android.media.IAidlNode;
+
+/**
+ * Binder interface for configuring/controlling a Codec2 AIDL encoder instance
+ * on behalf of a Surface which will produce input buffers.
+ *
+ * In order to support Persistent InputSurface and/or MediaRecorder.
+ */
+interface IAidlGraphicBufferSource {
+ void configure(IAidlNode node, Dataspace dataSpace);
+ void setSuspend(boolean suspend, long suspendTimeUs);
+ void setRepeatPreviousFrameDelayUs(long repeatAfterUs);
+ void setMaxFps(float maxFps);
+ void setTimeLapseConfig(double fps, double captureFps);
+ void setStartTimeUs(long startTimeUs);
+ void setStopTimeUs(long stopTimeUs);
+ long getStopTimeOffsetUs();
+ void setColorAspects(in AidlColorAspects aspects);
+ void setTimeOffsetUs(long timeOffsetsUs);
+ void signalEndOfInputStream();
+}
diff --git a/media/module/aidlpersistentsurface/aidl/android/media/IAidlNode.aidl b/media/module/aidlpersistentsurface/aidl/android/media/IAidlNode.aidl
new file mode 100644
index 0000000..6cac19e
--- /dev/null
+++ b/media/module/aidlpersistentsurface/aidl/android/media/IAidlNode.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media;
+
+import android.hardware.HardwareBuffer;
+import android.media.IAidlBufferSource;
+import android.os.ParcelFileDescriptor;
+
+/**
+ * Binder interface abstraction for codec2 encoder instance.
+ *
+ * In order to support Persistent InputSurface and/or MediaRecorder.
+ */
+interface IAidlNode {
+
+ /**
+ * InputBuffer parameter for retrieval for the Node
+ */
+ parcelable InputBufferParams {
+ int bufferCountActual;
+ int frameWidth;
+ int frameHeight;
+ }
+
+ void freeNode();
+ void sendCommand(int cmd, int param);
+ long getConsumerUsage();
+ InputBufferParams getInputBufferParams();
+ void setConsumerUsage(long usage);
+ void setAdjustTimestampGapUs(int gapUs);
+ void setInputSurface(IAidlBufferSource bufferSource);
+ void submitBuffer(
+ int buffer,
+ in HardwareBuffer hBuffer,
+ int flags,
+ long timestampUs,
+ in @nullable ParcelFileDescriptor fence);
+ void onDataSpaceChanged(int dataSpace, int aspects, int pixelFormat);
+}
diff --git a/media/module/aidlpersistentsurface/include/media/stagefright/aidlpersistentsurface/AidlGraphicBufferSource.h b/media/module/aidlpersistentsurface/include/media/stagefright/aidlpersistentsurface/AidlGraphicBufferSource.h
new file mode 100644
index 0000000..4b38294
--- /dev/null
+++ b/media/module/aidlpersistentsurface/include/media/stagefright/aidlpersistentsurface/AidlGraphicBufferSource.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <media/stagefright/bqhelper/GraphicBufferSource.h>
+#include <media/stagefright/foundation/ABase.h>
+
+#include <media/stagefright/aidlpersistentsurface/IAidlNodeWrapper.h>
+
+#include <utils/Errors.h>
+
+#include <aidl/android/media/BnAidlBufferSource.h>
+
+namespace android::media {
+
+/*
+ * This class is used to emulate feed OMX codecs from a Surface via BufferQueue or
+ * HW producer using AIDL binder interfaces.
+ *
+ * See media/stagefright/bqhelper/GraphicBufferSource.h for documentation.
+ */
+class AidlGraphicBufferSource : public GraphicBufferSource {
+public:
+ AidlGraphicBufferSource() = default;
+ virtual ~AidlGraphicBufferSource() = default;
+
+ // For IAidlBufferSource interface
+ // ------------------------------
+
+ // When we can start handling buffers. If we already have buffers of data
+ // sitting in the BufferQueue, this will send them to the codec.
+ ::ndk::ScopedAStatus onStart();
+
+ // When the codec is meant to return all buffers back to the client for
+ // them to be freed. Do NOT submit any more buffers to the component.
+ ::ndk::ScopedAStatus onStop();
+
+ // When we are shutting down.
+ ::ndk::ScopedAStatus onRelease();
+
+ // Rest of the interface in GraphicBufferSource.
+
+ // IAidlGraphicBufferSource interface
+ // ------------------------------
+
+ // Configure the buffer source to be used with a codec2 aidl node given
+ // parameters.
+ status_t configure(
+ const sp<IAidlNodeWrapper> &aidlNode,
+ int32_t dataSpace,
+ int32_t bufferCount,
+ uint32_t frameWidth,
+ uint32_t frameHeight,
+ uint64_t consumerUsage);
+
+ // Rest of the interface in GraphicBufferSource.
+
+private:
+ DISALLOW_EVIL_CONSTRUCTORS(AidlGraphicBufferSource);
+};
+
+} // namespace android::media
diff --git a/media/module/aidlpersistentsurface/include/media/stagefright/aidlpersistentsurface/C2NodeDef.h b/media/module/aidlpersistentsurface/include/media/stagefright/aidlpersistentsurface/C2NodeDef.h
new file mode 100644
index 0000000..64de7ae
--- /dev/null
+++ b/media/module/aidlpersistentsurface/include/media/stagefright/aidlpersistentsurface/C2NodeDef.h
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+namespace android::media {
+
+// Node definitions for aidl input surface.
+//
+// Copied from non-aidl version implementation.
+// Unnecessary definitions for input surface implementation
+// are all omitted.
+
+enum C2NodeBufferFlag : uint32_t {
+ BUFFERFLAG_EOS = 1,
+ BUFFERFLAG_ENDOFFRAME = (1 << 4)
+};
+
+enum C2NodeCommand : int32_t {
+ CommandStateSet = 1
+};
+
+enum C2NodeStatus : int32_t {
+ NodeStatusLoaded = 1
+};
+
+} // namespace android::media
diff --git a/media/module/aidlpersistentsurface/include/media/stagefright/aidlpersistentsurface/IAidlNodeWrapper.h b/media/module/aidlpersistentsurface/include/media/stagefright/aidlpersistentsurface/IAidlNodeWrapper.h
new file mode 100644
index 0000000..f23b5e4
--- /dev/null
+++ b/media/module/aidlpersistentsurface/include/media/stagefright/aidlpersistentsurface/IAidlNodeWrapper.h
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <utils/RefBase.h>
+#include <utils/StrongPointer.h>
+#include <ui/GraphicBuffer.h>
+
+#include <stdint.h>
+
+namespace android::media {
+
+struct IAidlNodeWrapper : public RefBase {
+ virtual status_t submitBuffer(
+ int32_t bufferId, uint32_t flags,
+ const sp<GraphicBuffer> &buffer = nullptr,
+ int64_t timestamp = 0, int fenceFd = -1) = 0;
+ virtual void dispatchDataSpaceChanged(
+ int32_t dataSpace, int32_t aspects, int32_t pixelFormat) = 0;
+};
+
+} // namespace android::media
diff --git a/media/module/aidlpersistentsurface/include/media/stagefright/aidlpersistentsurface/wrapper/Conversion.h b/media/module/aidlpersistentsurface/include/media/stagefright/aidlpersistentsurface/wrapper/Conversion.h
new file mode 100644
index 0000000..dcb83f6
--- /dev/null
+++ b/media/module/aidlpersistentsurface/include/media/stagefright/aidlpersistentsurface/wrapper/Conversion.h
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/binder_auto_utils.h>
+#include <ui/GraphicBuffer.h>
+#include <utils/Errors.h>
+
+#include <aidl/android/hardware/graphics/common/Dataspace.h>
+#include <aidl/android/hardware/graphics/common/PixelFormat.h>
+#include <aidl/android/media/AidlColorAspects.h>
+
+namespace android::media::aidl_conversion {
+
+inline status_t fromAidlStatus(const ::ndk::ScopedAStatus &status) {
+ if (!status.isOk()) {
+ if (status.getExceptionCode() == EX_SERVICE_SPECIFIC) {
+ return static_cast<status_t>(status.getServiceSpecificError());
+ } else {
+ return static_cast<status_t>(FAILED_TRANSACTION);
+ }
+ }
+ return NO_ERROR;
+}
+
+inline ::ndk::ScopedAStatus toAidlStatus(status_t status) {
+ if (status == NO_ERROR) {
+ return ::ndk::ScopedAStatus::ok();
+ }
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(status);
+}
+
+inline int32_t compactFromAidlColorAspects(::aidl::android::media::AidlColorAspects const& s) {
+ return static_cast<int32_t>(
+ (static_cast<uint32_t>(s.range) << 24) |
+ (static_cast<uint32_t>(s.primaries) << 16) |
+ (static_cast<uint32_t>(s.transfer)) |
+ (static_cast<uint32_t>(s.matrixCoeffs) << 8));
+}
+
+inline int32_t rawFromAidlDataspace(
+ ::aidl::android::hardware::graphics::common::Dataspace const& s) {
+ return static_cast<int32_t>(s);
+}
+
+} // namespace android::media::aidl_conversion
diff --git a/media/module/aidlpersistentsurface/include/media/stagefright/aidlpersistentsurface/wrapper/WAidlGraphicBufferSource.h b/media/module/aidlpersistentsurface/include/media/stagefright/aidlpersistentsurface/wrapper/WAidlGraphicBufferSource.h
new file mode 100644
index 0000000..f4d7fe8
--- /dev/null
+++ b/media/module/aidlpersistentsurface/include/media/stagefright/aidlpersistentsurface/wrapper/WAidlGraphicBufferSource.h
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <utils/RefBase.h>
+#include <aidl/android/hardware/graphics/common/Dataspace.h>
+#include <aidl/android/media/IAidlBufferSource.h>
+#include <aidl/android/media/IAidlNode.h>
+#include <aidl/android/media/BnAidlGraphicBufferSource.h>
+
+namespace android::media {
+
+class AidlGraphicBufferSource;
+
+using ::android::sp;
+
+/**
+ * Aidl wrapper implementation for IAidlGraphicBufferSource
+ */
+class WAidlGraphicBufferSource : public ::aidl::android::media::BnAidlGraphicBufferSource {
+public:
+
+ struct WAidlNodeWrapper;
+ class WAidlBufferSource;
+
+ sp<AidlGraphicBufferSource> mBase;
+ std::shared_ptr<::aidl::android::media::IAidlBufferSource> mBufferSource;
+
+ WAidlGraphicBufferSource(sp<AidlGraphicBufferSource> const& base);
+ ::ndk::ScopedAStatus configure(
+ const std::shared_ptr<::aidl::android::media::IAidlNode>& node,
+ aidl::android::hardware::graphics::common::Dataspace dataspace) override;
+ ::ndk::ScopedAStatus setSuspend(bool suspend, int64_t timeUs) override;
+ ::ndk::ScopedAStatus setRepeatPreviousFrameDelayUs(int64_t repeatAfterUs) override;
+ ::ndk::ScopedAStatus setMaxFps(float maxFps) override;
+ ::ndk::ScopedAStatus setTimeLapseConfig(double fps, double captureFps) override;
+ ::ndk::ScopedAStatus setStartTimeUs(int64_t startTimeUs) override;
+ ::ndk::ScopedAStatus setStopTimeUs(int64_t stopTimeUs) override;
+ ::ndk::ScopedAStatus getStopTimeOffsetUs(int64_t *_aidl_return) override;
+ ::ndk::ScopedAStatus setColorAspects(
+ const ::aidl::android::media::AidlColorAspects& aspects) override;
+ ::ndk::ScopedAStatus setTimeOffsetUs(int64_t timeOffsetUs) override;
+ ::ndk::ScopedAStatus signalEndOfInputStream() override;
+};
+
+} // namespace android::media
diff --git a/media/module/aidlpersistentsurface/wrapper/WAidlGraphicBufferSource.cpp b/media/module/aidlpersistentsurface/wrapper/WAidlGraphicBufferSource.cpp
new file mode 100644
index 0000000..5526b10
--- /dev/null
+++ b/media/module/aidlpersistentsurface/wrapper/WAidlGraphicBufferSource.cpp
@@ -0,0 +1,221 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//#define LOG_NDEBUG 0
+#define LOG_TAG "WAidlGraphicBufferSource"
+#include <android/hardware_buffer_aidl.h>
+#include <private/android/AHardwareBufferHelpers.h>
+#include <utils/Log.h>
+
+#include <aidl/android/media/BnAidlBufferSource.h>
+#include <aidl/android/media/IAidlNode.h>
+
+#include <media/stagefright/aidlpersistentsurface/AidlGraphicBufferSource.h>
+#include <media/stagefright/aidlpersistentsurface/C2NodeDef.h>
+#include <media/stagefright/aidlpersistentsurface/wrapper/WAidlGraphicBufferSource.h>
+#include <media/stagefright/aidlpersistentsurface/wrapper/Conversion.h>
+
+namespace android::media {
+using ::android::binder::unique_fd;
+using ::aidl::android::hardware::graphics::common::PixelFormat;
+using ::aidl::android::hardware::graphics::common::Dataspace;
+using ::aidl::android::media::AidlColorAspects;
+using ::aidl::android::media::IAidlNode;
+using ::aidl::android::media::BnAidlBufferSource;
+
+// Conversion
+using ::android::media::aidl_conversion::fromAidlStatus;
+using ::android::media::aidl_conversion::toAidlStatus;
+using ::android::media::aidl_conversion::compactFromAidlColorAspects;
+using ::android::media::aidl_conversion::rawFromAidlDataspace;
+
+struct WAidlGraphicBufferSource::WAidlNodeWrapper : public IAidlNodeWrapper {
+ std::shared_ptr<IAidlNode> mNode;
+
+ WAidlNodeWrapper(const std::shared_ptr<IAidlNode> &node): mNode(node) {
+ }
+
+ virtual status_t submitBuffer(
+ int32_t bufferId, uint32_t flags,
+ const sp<GraphicBuffer> &buffer,
+ int64_t timestamp, int fenceFd) override {
+ AHardwareBuffer *ahwBuffer = nullptr;
+ ::aidl::android::hardware::HardwareBuffer hBuffer;
+ if (buffer.get()) {
+ ahwBuffer = AHardwareBuffer_from_GraphicBuffer(buffer.get());
+ AHardwareBuffer_acquire(ahwBuffer);
+ hBuffer.reset(ahwBuffer);
+ }
+
+ ::ndk::ScopedFileDescriptor fence(fenceFd);
+
+ return fromAidlStatus(mNode->submitBuffer(
+ bufferId,
+ hBuffer,
+ flags,
+ timestamp,
+ fence));
+ }
+
+ virtual void dispatchDataSpaceChanged(
+ int32_t dataSpace, int32_t aspects, int32_t pixelFormat) override {
+ ::ndk::ScopedAStatus err = mNode->onDataSpaceChanged(
+ dataSpace, aspects, pixelFormat);
+ status_t status = fromAidlStatus(err);
+ if (status != NO_ERROR) {
+ ALOGE("WAidlNodeWrapper failed to change dataspace (%d): "
+ "dataSpace = %ld, aspects = %ld, pixelFormat = %ld",
+ static_cast<int>(status),
+ static_cast<long>(dataSpace),
+ static_cast<long>(aspects),
+ static_cast<long>(pixelFormat));
+ }
+ }
+};
+
+class WAidlGraphicBufferSource::WAidlBufferSource : public BnAidlBufferSource {
+ sp<AidlGraphicBufferSource> mSource;
+
+public:
+ WAidlBufferSource(const sp<AidlGraphicBufferSource> &source): mSource(source) {
+ }
+
+ ::ndk::ScopedAStatus onStart() override {
+ mSource->onStart();
+ return ::ndk::ScopedAStatus::ok();
+ }
+
+ ::ndk::ScopedAStatus onStop() override {
+ mSource->onStop();
+ return ::ndk::ScopedAStatus::ok();
+ }
+
+ ::ndk::ScopedAStatus onRelease() override {
+ mSource->onRelease();
+ return ::ndk::ScopedAStatus::ok();
+ }
+
+ ::ndk::ScopedAStatus onInputBufferAdded(int32_t bufferId) override {
+ mSource->onInputBufferAdded(bufferId);
+ return ::ndk::ScopedAStatus::ok();
+ }
+
+ ::ndk::ScopedAStatus onInputBufferEmptied(
+ int32_t bufferId, const ::ndk::ScopedFileDescriptor& fence) override {
+ mSource->onInputBufferEmptied(bufferId, ::dup(fence.get()));
+ return ::ndk::ScopedAStatus::ok();
+ }
+};
+
+// WAidlGraphicBufferSource
+WAidlGraphicBufferSource::WAidlGraphicBufferSource(
+ sp<AidlGraphicBufferSource> const& base) :
+ mBase(base),
+ mBufferSource(::ndk::SharedRefBase::make<WAidlBufferSource>(base)) {
+}
+
+::ndk::ScopedAStatus WAidlGraphicBufferSource::configure(
+ const std::shared_ptr<IAidlNode>& node, Dataspace dataspace) {
+ if (node == NULL) {
+ return toAidlStatus(BAD_VALUE);
+ }
+
+ // Do setInputSurface() first, the node will try to enable metadata
+ // mode on input, and does necessary error checking. If this fails,
+ // we can't use this input surface on the node.
+ ::ndk::ScopedAStatus err = node->setInputSurface(mBufferSource);
+ status_t fnStatus = fromAidlStatus(err);
+ if (fnStatus != NO_ERROR) {
+ ALOGE("Unable to set input surface: %d", fnStatus);
+ return err;
+ }
+
+ // use consumer usage bits queried from encoder, but always add
+ // HW_VIDEO_ENCODER for backward compatibility.
+ int64_t consumerUsage;
+ fnStatus = OK;
+ err = node->getConsumerUsage(&consumerUsage);
+ fnStatus = fromAidlStatus(err);
+ if (fnStatus != NO_ERROR) {
+ if (fnStatus == FAILED_TRANSACTION) {
+ return err;
+ }
+ consumerUsage = 0;
+ }
+
+ IAidlNode::InputBufferParams rDef ;
+ err = node->getInputBufferParams(&rDef);
+ fnStatus = fromAidlStatus(err);
+ if (fnStatus != NO_ERROR) {
+ ALOGE("Failed to get port definition: %d", fnStatus);
+ return toAidlStatus(fnStatus);
+ }
+
+ return toAidlStatus(mBase->configure(
+ new WAidlNodeWrapper(node),
+ rawFromAidlDataspace(dataspace),
+ rDef.bufferCountActual,
+ rDef.frameWidth,
+ rDef.frameHeight,
+ static_cast<uint64_t>(consumerUsage)));
+}
+
+::ndk::ScopedAStatus WAidlGraphicBufferSource::setSuspend(
+ bool suspend, int64_t timeUs) {
+ return toAidlStatus(mBase->setSuspend(suspend, timeUs));
+}
+
+::ndk::ScopedAStatus WAidlGraphicBufferSource::setRepeatPreviousFrameDelayUs(
+ int64_t repeatAfterUs) {
+ return toAidlStatus(mBase->setRepeatPreviousFrameDelayUs(repeatAfterUs));
+}
+
+::ndk::ScopedAStatus WAidlGraphicBufferSource::setMaxFps(float maxFps) {
+ return toAidlStatus(mBase->setMaxFps(maxFps));
+}
+
+::ndk::ScopedAStatus WAidlGraphicBufferSource::setTimeLapseConfig(
+ double fps, double captureFps) {
+ return toAidlStatus(mBase->setTimeLapseConfig(fps, captureFps));
+}
+
+::ndk::ScopedAStatus WAidlGraphicBufferSource::setStartTimeUs(int64_t startTimeUs) {
+ return toAidlStatus(mBase->setStartTimeUs(startTimeUs));
+}
+
+::ndk::ScopedAStatus WAidlGraphicBufferSource::setStopTimeUs(int64_t stopTimeUs) {
+ return toAidlStatus(mBase->setStopTimeUs(stopTimeUs));
+}
+
+::ndk::ScopedAStatus WAidlGraphicBufferSource::getStopTimeOffsetUs(int64_t* _aidl_return) {
+ status_t status = mBase->getStopTimeOffsetUs(_aidl_return);
+ return toAidlStatus(status);
+}
+
+::ndk::ScopedAStatus WAidlGraphicBufferSource::setColorAspects(
+ const AidlColorAspects& aspects) {
+ return toAidlStatus(mBase->setColorAspects(compactFromAidlColorAspects(aspects)));
+}
+
+::ndk::ScopedAStatus WAidlGraphicBufferSource::setTimeOffsetUs(int64_t timeOffsetUs) {
+ return toAidlStatus(mBase->setTimeOffsetUs(timeOffsetUs));
+}
+
+::ndk::ScopedAStatus WAidlGraphicBufferSource::signalEndOfInputStream() {
+ return toAidlStatus(mBase->signalEndOfInputStream());
+}
+
+
+} // namespace android::media