1 /*
2 * Copyright 2024, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 //#define LOG_NDEBUG 0
17 #define LOG_TAG "WAidlGraphicBufferSource"
18 #include <android/hardware_buffer_aidl.h>
19 #include <private/android/AHardwareBufferHelpers.h>
20 #include <utils/Log.h>
21
22 #include <aidl/android/media/BnAidlBufferSource.h>
23 #include <aidl/android/media/IAidlNode.h>
24
25 #include <media/stagefright/aidlpersistentsurface/AidlGraphicBufferSource.h>
26 #include <media/stagefright/aidlpersistentsurface/C2NodeDef.h>
27 #include <media/stagefright/aidlpersistentsurface/wrapper/WAidlGraphicBufferSource.h>
28 #include <media/stagefright/aidlpersistentsurface/wrapper/Conversion.h>
29
30 namespace android::media {
31 using ::android::binder::unique_fd;
32 using ::aidl::android::hardware::graphics::common::PixelFormat;
33 using ::aidl::android::hardware::graphics::common::Dataspace;
34 using ::aidl::android::media::AidlColorAspects;
35 using ::aidl::android::media::IAidlNode;
36 using ::aidl::android::media::BnAidlBufferSource;
37
38 // Conversion
39 using ::android::media::aidl_conversion::fromAidlStatus;
40 using ::android::media::aidl_conversion::toAidlStatus;
41 using ::android::media::aidl_conversion::compactFromAidlColorAspects;
42 using ::android::media::aidl_conversion::rawFromAidlDataspace;
43
44 struct WAidlGraphicBufferSource::WAidlNodeWrapper : public IAidlNodeWrapper {
45 std::shared_ptr<IAidlNode> mNode;
46
WAidlNodeWrapperandroid::media::WAidlGraphicBufferSource::WAidlNodeWrapper47 WAidlNodeWrapper(const std::shared_ptr<IAidlNode> &node): mNode(node) {
48 }
49
submitBufferandroid::media::WAidlGraphicBufferSource::WAidlNodeWrapper50 virtual status_t submitBuffer(
51 int32_t bufferId, uint32_t flags,
52 const sp<GraphicBuffer> &buffer,
53 int64_t timestamp, int fenceFd) override {
54 ::ndk::ScopedFileDescriptor fence(fenceFd);
55 if (buffer.get()) {
56 ::aidl::android::hardware::HardwareBuffer hBuffer;
57 AHardwareBuffer *ahwBuffer = AHardwareBuffer_from_GraphicBuffer(buffer.get());
58 AHardwareBuffer_acquire(ahwBuffer);
59 hBuffer.reset(ahwBuffer);
60
61 return fromAidlStatus(mNode->submitBuffer(
62 bufferId,
63 std::move(hBuffer),
64 flags,
65 timestamp,
66 fence));
67 }
68
69 return fromAidlStatus(mNode->submitBuffer(
70 bufferId,
71 {},
72 flags,
73 timestamp,
74 fence));
75 }
76
dispatchDataSpaceChangedandroid::media::WAidlGraphicBufferSource::WAidlNodeWrapper77 virtual void dispatchDataSpaceChanged(
78 int32_t dataSpace, int32_t aspects, int32_t pixelFormat) override {
79 ::ndk::ScopedAStatus err = mNode->onDataSpaceChanged(
80 dataSpace, aspects, pixelFormat);
81 status_t status = fromAidlStatus(err);
82 if (status != NO_ERROR) {
83 ALOGE("WAidlNodeWrapper failed to change dataspace (%d): "
84 "dataSpace = %ld, aspects = %ld, pixelFormat = %ld",
85 static_cast<int>(status),
86 static_cast<long>(dataSpace),
87 static_cast<long>(aspects),
88 static_cast<long>(pixelFormat));
89 }
90 }
91 };
92
93 class WAidlGraphicBufferSource::WAidlBufferSource : public BnAidlBufferSource {
94 sp<AidlGraphicBufferSource> mSource;
95
96 public:
WAidlBufferSource(const sp<AidlGraphicBufferSource> & source)97 WAidlBufferSource(const sp<AidlGraphicBufferSource> &source): mSource(source) {
98 }
99
onStart()100 ::ndk::ScopedAStatus onStart() override {
101 mSource->onStart();
102 return ::ndk::ScopedAStatus::ok();
103 }
104
onStop()105 ::ndk::ScopedAStatus onStop() override {
106 mSource->onStop();
107 return ::ndk::ScopedAStatus::ok();
108 }
109
onRelease()110 ::ndk::ScopedAStatus onRelease() override {
111 mSource->onRelease();
112 return ::ndk::ScopedAStatus::ok();
113 }
114
onInputBufferAdded(int32_t bufferId)115 ::ndk::ScopedAStatus onInputBufferAdded(int32_t bufferId) override {
116 mSource->onInputBufferAdded(bufferId);
117 return ::ndk::ScopedAStatus::ok();
118 }
119
onInputBufferEmptied(int32_t bufferId,const::ndk::ScopedFileDescriptor & fence)120 ::ndk::ScopedAStatus onInputBufferEmptied(
121 int32_t bufferId, const ::ndk::ScopedFileDescriptor& fence) override {
122 mSource->onInputBufferEmptied(bufferId, ::dup(fence.get()));
123 return ::ndk::ScopedAStatus::ok();
124 }
125 };
126
127 // WAidlGraphicBufferSource
WAidlGraphicBufferSource(sp<AidlGraphicBufferSource> const & base)128 WAidlGraphicBufferSource::WAidlGraphicBufferSource(
129 sp<AidlGraphicBufferSource> const& base) :
130 mBase(base),
131 mBufferSource(::ndk::SharedRefBase::make<WAidlBufferSource>(base)) {
132 }
133
configure(const std::shared_ptr<IAidlNode> & node,Dataspace dataspace)134 ::ndk::ScopedAStatus WAidlGraphicBufferSource::configure(
135 const std::shared_ptr<IAidlNode>& node, Dataspace dataspace) {
136 if (node == NULL) {
137 return toAidlStatus(BAD_VALUE);
138 }
139
140 // Do setInputSurface() first, the node will try to enable metadata
141 // mode on input, and does necessary error checking. If this fails,
142 // we can't use this input surface on the node.
143 ::ndk::ScopedAStatus err = node->setInputSurface(mBufferSource);
144 status_t fnStatus = fromAidlStatus(err);
145 if (fnStatus != NO_ERROR) {
146 ALOGE("Unable to set input surface: %d", fnStatus);
147 return err;
148 }
149
150 // use consumer usage bits queried from encoder, but always add
151 // HW_VIDEO_ENCODER for backward compatibility.
152 int64_t consumerUsage;
153 fnStatus = OK;
154 err = node->getConsumerUsage(&consumerUsage);
155 fnStatus = fromAidlStatus(err);
156 if (fnStatus != NO_ERROR) {
157 if (fnStatus == FAILED_TRANSACTION) {
158 return err;
159 }
160 consumerUsage = 0;
161 }
162
163 IAidlNode::InputBufferParams rDef ;
164 err = node->getInputBufferParams(&rDef);
165 fnStatus = fromAidlStatus(err);
166 if (fnStatus != NO_ERROR) {
167 ALOGE("Failed to get port definition: %d", fnStatus);
168 return toAidlStatus(fnStatus);
169 }
170
171 return toAidlStatus(mBase->configure(
172 new WAidlNodeWrapper(node),
173 rawFromAidlDataspace(dataspace),
174 rDef.bufferCountActual,
175 rDef.frameWidth,
176 rDef.frameHeight,
177 static_cast<uint64_t>(consumerUsage)));
178 }
179
setSuspend(bool suspend,int64_t timeUs)180 ::ndk::ScopedAStatus WAidlGraphicBufferSource::setSuspend(
181 bool suspend, int64_t timeUs) {
182 return toAidlStatus(mBase->setSuspend(suspend, timeUs));
183 }
184
setRepeatPreviousFrameDelayUs(int64_t repeatAfterUs)185 ::ndk::ScopedAStatus WAidlGraphicBufferSource::setRepeatPreviousFrameDelayUs(
186 int64_t repeatAfterUs) {
187 return toAidlStatus(mBase->setRepeatPreviousFrameDelayUs(repeatAfterUs));
188 }
189
setMaxFps(float maxFps)190 ::ndk::ScopedAStatus WAidlGraphicBufferSource::setMaxFps(float maxFps) {
191 return toAidlStatus(mBase->setMaxFps(maxFps));
192 }
193
setTimeLapseConfig(double fps,double captureFps)194 ::ndk::ScopedAStatus WAidlGraphicBufferSource::setTimeLapseConfig(
195 double fps, double captureFps) {
196 return toAidlStatus(mBase->setTimeLapseConfig(fps, captureFps));
197 }
198
setStartTimeUs(int64_t startTimeUs)199 ::ndk::ScopedAStatus WAidlGraphicBufferSource::setStartTimeUs(int64_t startTimeUs) {
200 return toAidlStatus(mBase->setStartTimeUs(startTimeUs));
201 }
202
setStopTimeUs(int64_t stopTimeUs)203 ::ndk::ScopedAStatus WAidlGraphicBufferSource::setStopTimeUs(int64_t stopTimeUs) {
204 return toAidlStatus(mBase->setStopTimeUs(stopTimeUs));
205 }
206
getStopTimeOffsetUs(int64_t * _aidl_return)207 ::ndk::ScopedAStatus WAidlGraphicBufferSource::getStopTimeOffsetUs(int64_t* _aidl_return) {
208 status_t status = mBase->getStopTimeOffsetUs(_aidl_return);
209 return toAidlStatus(status);
210 }
211
setColorAspects(const AidlColorAspects & aspects)212 ::ndk::ScopedAStatus WAidlGraphicBufferSource::setColorAspects(
213 const AidlColorAspects& aspects) {
214 return toAidlStatus(mBase->setColorAspects(compactFromAidlColorAspects(aspects)));
215 }
216
setTimeOffsetUs(int64_t timeOffsetUs)217 ::ndk::ScopedAStatus WAidlGraphicBufferSource::setTimeOffsetUs(int64_t timeOffsetUs) {
218 return toAidlStatus(mBase->setTimeOffsetUs(timeOffsetUs));
219 }
220
signalEndOfInputStream()221 ::ndk::ScopedAStatus WAidlGraphicBufferSource::signalEndOfInputStream() {
222 return toAidlStatus(mBase->signalEndOfInputStream());
223 }
224
225
226 } // namespace android::media
227