1 /* 2 * Copyright 2016, 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 17 #define LOG_TAG "WGraphicBufferProducer-impl" 18 19 #include <android-base/logging.h> 20 21 #include <media/stagefright/omx/1.0/WGraphicBufferProducer.h> 22 #include <media/stagefright/omx/1.0/WProducerListener.h> 23 #include <media/stagefright/omx/1.0/Conversion.h> 24 #include <system/window.h> 25 26 namespace android { 27 namespace hardware { 28 namespace media { 29 namespace omx { 30 namespace V1_0 { 31 namespace implementation { 32 33 // TWGraphicBufferProducer 34 TWGraphicBufferProducer::TWGraphicBufferProducer( 35 sp<BGraphicBufferProducer> const& base): 36 mBase(base) { 37 } 38 39 Return<void> TWGraphicBufferProducer::requestBuffer( 40 int32_t slot, requestBuffer_cb _hidl_cb) { 41 sp<GraphicBuffer> buf; 42 status_t status = mBase->requestBuffer(slot, &buf); 43 AnwBuffer anwBuffer; 44 if (buf != nullptr) { 45 wrapAs(&anwBuffer, *buf); 46 } 47 _hidl_cb(static_cast<int32_t>(status), anwBuffer); 48 return Void(); 49 } 50 51 Return<int32_t> TWGraphicBufferProducer::setMaxDequeuedBufferCount( 52 int32_t maxDequeuedBuffers) { 53 return static_cast<int32_t>(mBase->setMaxDequeuedBufferCount( 54 static_cast<int>(maxDequeuedBuffers))); 55 } 56 57 Return<int32_t> TWGraphicBufferProducer::setAsyncMode(bool async) { 58 return static_cast<int32_t>(mBase->setAsyncMode(async)); 59 } 60 61 Return<void> TWGraphicBufferProducer::dequeueBuffer( 62 uint32_t width, uint32_t height, 63 PixelFormat format, uint32_t usage, 64 bool getFrameTimestamps, dequeueBuffer_cb _hidl_cb) { 65 int slot; 66 sp<Fence> fence; 67 ::android::FrameEventHistoryDelta outTimestamps; 68 status_t status = mBase->dequeueBuffer( 69 &slot, &fence, width, height, 70 static_cast<::android::PixelFormat>(format), usage, nullptr, 71 getFrameTimestamps ? &outTimestamps : nullptr); 72 hidl_handle tFence; 73 FrameEventHistoryDelta tOutTimestamps; 74 75 native_handle_t* nh = nullptr; 76 if ((fence == nullptr) || !wrapAs(&tFence, &nh, *fence)) { 77 LOG(ERROR) << "TWGraphicBufferProducer::dequeueBuffer - " 78 "Invalid output fence"; 79 _hidl_cb(static_cast<int32_t>(status), 80 static_cast<int32_t>(slot), 81 tFence, 82 tOutTimestamps); 83 return Void(); 84 } 85 std::vector<std::vector<native_handle_t*> > nhAA; 86 if (getFrameTimestamps && !wrapAs(&tOutTimestamps, &nhAA, outTimestamps)) { 87 LOG(ERROR) << "TWGraphicBufferProducer::dequeueBuffer - " 88 "Invalid output timestamps"; 89 _hidl_cb(static_cast<int32_t>(status), 90 static_cast<int32_t>(slot), 91 tFence, 92 tOutTimestamps); 93 native_handle_delete(nh); 94 return Void(); 95 } 96 97 _hidl_cb(static_cast<int32_t>(status), 98 static_cast<int32_t>(slot), 99 tFence, 100 tOutTimestamps); 101 native_handle_delete(nh); 102 if (getFrameTimestamps) { 103 for (auto& nhA : nhAA) { 104 for (auto& handle : nhA) { 105 native_handle_delete(handle); 106 } 107 } 108 } 109 return Void(); 110 } 111 112 Return<int32_t> TWGraphicBufferProducer::detachBuffer(int32_t slot) { 113 return static_cast<int32_t>(mBase->detachBuffer(slot)); 114 } 115 116 Return<void> TWGraphicBufferProducer::detachNextBuffer( 117 detachNextBuffer_cb _hidl_cb) { 118 sp<GraphicBuffer> outBuffer; 119 sp<Fence> outFence; 120 status_t status = mBase->detachNextBuffer(&outBuffer, &outFence); 121 AnwBuffer tBuffer; 122 hidl_handle tFence; 123 124 if (outBuffer == nullptr) { 125 LOG(ERROR) << "TWGraphicBufferProducer::detachNextBuffer - " 126 "Invalid output buffer"; 127 _hidl_cb(static_cast<int32_t>(status), tBuffer, tFence); 128 return Void(); 129 } 130 wrapAs(&tBuffer, *outBuffer); 131 native_handle_t* nh = nullptr; 132 if ((outFence != nullptr) && !wrapAs(&tFence, &nh, *outFence)) { 133 LOG(ERROR) << "TWGraphicBufferProducer::detachNextBuffer - " 134 "Invalid output fence"; 135 _hidl_cb(static_cast<int32_t>(status), tBuffer, tFence); 136 return Void(); 137 } 138 139 _hidl_cb(static_cast<int32_t>(status), tBuffer, tFence); 140 native_handle_delete(nh); 141 return Void(); 142 } 143 144 Return<void> TWGraphicBufferProducer::attachBuffer( 145 const AnwBuffer& buffer, 146 attachBuffer_cb _hidl_cb) { 147 int outSlot; 148 sp<GraphicBuffer> lBuffer = new GraphicBuffer(); 149 if (!convertTo(lBuffer.get(), buffer)) { 150 LOG(ERROR) << "TWGraphicBufferProducer::attachBuffer - " 151 "Invalid input native window buffer"; 152 _hidl_cb(static_cast<int32_t>(BAD_VALUE), -1); 153 return Void(); 154 } 155 status_t status = mBase->attachBuffer(&outSlot, lBuffer); 156 157 _hidl_cb(static_cast<int32_t>(status), static_cast<int32_t>(outSlot)); 158 return Void(); 159 } 160 161 Return<void> TWGraphicBufferProducer::queueBuffer( 162 int32_t slot, const QueueBufferInput& input, 163 queueBuffer_cb _hidl_cb) { 164 QueueBufferOutput tOutput; 165 BGraphicBufferProducer::QueueBufferInput lInput( 166 0, false, HAL_DATASPACE_UNKNOWN, 167 ::android::Rect(0, 0, 1, 1), 168 NATIVE_WINDOW_SCALING_MODE_FREEZE, 169 0, ::android::Fence::NO_FENCE); 170 if (!convertTo(&lInput, input)) { 171 LOG(ERROR) << "TWGraphicBufferProducer::queueBuffer - " 172 "Invalid input"; 173 _hidl_cb(static_cast<int32_t>(BAD_VALUE), tOutput); 174 return Void(); 175 } 176 BGraphicBufferProducer::QueueBufferOutput lOutput; 177 status_t status = mBase->queueBuffer( 178 static_cast<int>(slot), lInput, &lOutput); 179 180 std::vector<std::vector<native_handle_t*> > nhAA; 181 if (!wrapAs(&tOutput, &nhAA, lOutput)) { 182 LOG(ERROR) << "TWGraphicBufferProducer::queueBuffer - " 183 "Invalid output"; 184 _hidl_cb(static_cast<int32_t>(BAD_VALUE), tOutput); 185 return Void(); 186 } 187 188 _hidl_cb(static_cast<int32_t>(status), tOutput); 189 for (auto& nhA : nhAA) { 190 for (auto& nh : nhA) { 191 native_handle_delete(nh); 192 } 193 } 194 return Void(); 195 } 196 197 Return<int32_t> TWGraphicBufferProducer::cancelBuffer( 198 int32_t slot, const hidl_handle& fence) { 199 sp<Fence> lFence = new Fence(); 200 if (!convertTo(lFence.get(), fence)) { 201 LOG(ERROR) << "TWGraphicBufferProducer::cancelBuffer - " 202 "Invalid input fence"; 203 return static_cast<int32_t>(BAD_VALUE); 204 } 205 return static_cast<int32_t>(mBase->cancelBuffer(static_cast<int>(slot), lFence)); 206 } 207 208 Return<void> TWGraphicBufferProducer::query(int32_t what, query_cb _hidl_cb) { 209 int lValue; 210 int lReturn = mBase->query(static_cast<int>(what), &lValue); 211 _hidl_cb(static_cast<int32_t>(lReturn), static_cast<int32_t>(lValue)); 212 return Void(); 213 } 214 215 Return<void> TWGraphicBufferProducer::connect( 216 const sp<HProducerListener>& listener, 217 int32_t api, bool producerControlledByApp, connect_cb _hidl_cb) { 218 sp<BProducerListener> lListener = listener == nullptr ? 219 nullptr : new LWProducerListener(listener); 220 BGraphicBufferProducer::QueueBufferOutput lOutput; 221 status_t status = mBase->connect(lListener, 222 static_cast<int>(api), 223 producerControlledByApp, 224 &lOutput); 225 226 QueueBufferOutput tOutput; 227 std::vector<std::vector<native_handle_t*> > nhAA; 228 if (!wrapAs(&tOutput, &nhAA, lOutput)) { 229 LOG(ERROR) << "TWGraphicBufferProducer::connect - " 230 "Invalid output"; 231 _hidl_cb(static_cast<int32_t>(status), tOutput); 232 return Void(); 233 } 234 235 _hidl_cb(static_cast<int32_t>(status), tOutput); 236 for (auto& nhA : nhAA) { 237 for (auto& nh : nhA) { 238 native_handle_delete(nh); 239 } 240 } 241 return Void(); 242 } 243 244 Return<int32_t> TWGraphicBufferProducer::disconnect( 245 int32_t api, DisconnectMode mode) { 246 return static_cast<int32_t>(mBase->disconnect( 247 static_cast<int>(api), 248 toGuiDisconnectMode(mode))); 249 } 250 251 Return<int32_t> TWGraphicBufferProducer::setSidebandStream(const hidl_handle& stream) { 252 return static_cast<int32_t>(mBase->setSidebandStream(NativeHandle::create( 253 stream ? native_handle_clone(stream) : NULL, true))); 254 } 255 256 Return<void> TWGraphicBufferProducer::allocateBuffers( 257 uint32_t width, uint32_t height, PixelFormat format, uint32_t usage) { 258 mBase->allocateBuffers( 259 width, height, 260 static_cast<::android::PixelFormat>(format), 261 usage); 262 return Void(); 263 } 264 265 Return<int32_t> TWGraphicBufferProducer::allowAllocation(bool allow) { 266 return static_cast<int32_t>(mBase->allowAllocation(allow)); 267 } 268 269 Return<int32_t> TWGraphicBufferProducer::setGenerationNumber(uint32_t generationNumber) { 270 return static_cast<int32_t>(mBase->setGenerationNumber(generationNumber)); 271 } 272 273 Return<void> TWGraphicBufferProducer::getConsumerName(getConsumerName_cb _hidl_cb) { 274 _hidl_cb(mBase->getConsumerName().string()); 275 return Void(); 276 } 277 278 Return<int32_t> TWGraphicBufferProducer::setSharedBufferMode(bool sharedBufferMode) { 279 return static_cast<int32_t>(mBase->setSharedBufferMode(sharedBufferMode)); 280 } 281 282 Return<int32_t> TWGraphicBufferProducer::setAutoRefresh(bool autoRefresh) { 283 return static_cast<int32_t>(mBase->setAutoRefresh(autoRefresh)); 284 } 285 286 Return<int32_t> TWGraphicBufferProducer::setDequeueTimeout(int64_t timeoutNs) { 287 return static_cast<int32_t>(mBase->setDequeueTimeout(timeoutNs)); 288 } 289 290 Return<void> TWGraphicBufferProducer::getLastQueuedBuffer( 291 getLastQueuedBuffer_cb _hidl_cb) { 292 sp<GraphicBuffer> lOutBuffer = new GraphicBuffer(); 293 sp<Fence> lOutFence = new Fence(); 294 float lOutTransformMatrix[16]; 295 status_t status = mBase->getLastQueuedBuffer( 296 &lOutBuffer, &lOutFence, lOutTransformMatrix); 297 298 AnwBuffer tOutBuffer; 299 if (lOutBuffer != nullptr) { 300 wrapAs(&tOutBuffer, *lOutBuffer); 301 } 302 hidl_handle tOutFence; 303 native_handle_t* nh = nullptr; 304 if ((lOutFence == nullptr) || !wrapAs(&tOutFence, &nh, *lOutFence)) { 305 LOG(ERROR) << "TWGraphicBufferProducer::getLastQueuedBuffer - " 306 "Invalid output fence"; 307 _hidl_cb(static_cast<int32_t>(status), 308 tOutBuffer, 309 tOutFence, 310 hidl_array<float, 16>()); 311 return Void(); 312 } 313 hidl_array<float, 16> tOutTransformMatrix(lOutTransformMatrix); 314 315 _hidl_cb(static_cast<int32_t>(status), tOutBuffer, tOutFence, tOutTransformMatrix); 316 native_handle_delete(nh); 317 return Void(); 318 } 319 320 Return<void> TWGraphicBufferProducer::getFrameTimestamps( 321 getFrameTimestamps_cb _hidl_cb) { 322 ::android::FrameEventHistoryDelta lDelta; 323 mBase->getFrameTimestamps(&lDelta); 324 325 FrameEventHistoryDelta tDelta; 326 std::vector<std::vector<native_handle_t*> > nhAA; 327 if (!wrapAs(&tDelta, &nhAA, lDelta)) { 328 LOG(ERROR) << "TWGraphicBufferProducer::getFrameTimestamps - " 329 "Invalid output frame timestamps"; 330 _hidl_cb(tDelta); 331 return Void(); 332 } 333 334 _hidl_cb(tDelta); 335 for (auto& nhA : nhAA) { 336 for (auto& nh : nhA) { 337 native_handle_delete(nh); 338 } 339 } 340 return Void(); 341 } 342 343 Return<void> TWGraphicBufferProducer::getUniqueId(getUniqueId_cb _hidl_cb) { 344 uint64_t outId; 345 status_t status = mBase->getUniqueId(&outId); 346 _hidl_cb(static_cast<int32_t>(status), outId); 347 return Void(); 348 } 349 350 } // namespace implementation 351 } // namespace V1_0 352 } // namespace omx 353 } // namespace media 354 } // namespace hardware 355 } // namespace android 356