| /* |
| * Copyright 2016, 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_TAG "WGraphicBufferProducer-impl" |
| |
| #include <android-base/logging.h> |
| |
| #include "WGraphicBufferProducer.h" |
| #include "WProducerListener.h" |
| #include "Conversion.h" |
| |
| namespace android { |
| namespace hardware { |
| namespace media { |
| namespace omx { |
| namespace V1_0 { |
| namespace implementation { |
| |
| // TWGraphicBufferProducer |
| TWGraphicBufferProducer::TWGraphicBufferProducer( |
| sp<BGraphicBufferProducer> const& base): |
| mBase(base) { |
| } |
| |
| Return<void> TWGraphicBufferProducer::requestBuffer( |
| int32_t slot, requestBuffer_cb _hidl_cb) { |
| sp<GraphicBuffer> buf; |
| status_t status = mBase->requestBuffer(slot, &buf); |
| AnwBuffer anwBuffer; |
| wrapAs(&anwBuffer, *buf); |
| _hidl_cb(static_cast<int32_t>(status), anwBuffer); |
| return Void(); |
| } |
| |
| Return<int32_t> TWGraphicBufferProducer::setMaxDequeuedBufferCount( |
| int32_t maxDequeuedBuffers) { |
| return static_cast<int32_t>(mBase->setMaxDequeuedBufferCount( |
| static_cast<int>(maxDequeuedBuffers))); |
| } |
| |
| Return<int32_t> TWGraphicBufferProducer::setAsyncMode(bool async) { |
| return static_cast<int32_t>(mBase->setAsyncMode(async)); |
| } |
| |
| Return<void> TWGraphicBufferProducer::dequeueBuffer( |
| uint32_t width, uint32_t height, |
| PixelFormat format, uint32_t usage, |
| bool getFrameTimestamps, dequeueBuffer_cb _hidl_cb) { |
| int slot; |
| sp<Fence> fence; |
| ::android::FrameEventHistoryDelta outTimestamps; |
| status_t status = mBase->dequeueBuffer( |
| &slot, &fence, |
| width, height, |
| static_cast<::android::PixelFormat>(format), usage, |
| getFrameTimestamps ? &outTimestamps : nullptr); |
| hidl_handle tFence; |
| FrameEventHistoryDelta tOutTimestamps; |
| |
| native_handle_t* nh = nullptr; |
| if ((fence == nullptr) || !wrapAs(&tFence, &nh, *fence)) { |
| LOG(ERROR) << "TWGraphicBufferProducer::dequeueBuffer - " |
| "Invalid output fence"; |
| _hidl_cb(static_cast<int32_t>(status), |
| static_cast<int32_t>(slot), |
| tFence, |
| tOutTimestamps); |
| return Void(); |
| } |
| std::vector<std::vector<native_handle_t*> > nhAA; |
| if (getFrameTimestamps && !wrapAs(&tOutTimestamps, &nhAA, outTimestamps)) { |
| LOG(ERROR) << "TWGraphicBufferProducer::dequeueBuffer - " |
| "Invalid output timestamps"; |
| _hidl_cb(static_cast<int32_t>(status), |
| static_cast<int32_t>(slot), |
| tFence, |
| tOutTimestamps); |
| native_handle_delete(nh); |
| return Void(); |
| } |
| |
| _hidl_cb(static_cast<int32_t>(status), |
| static_cast<int32_t>(slot), |
| tFence, |
| tOutTimestamps); |
| native_handle_delete(nh); |
| if (getFrameTimestamps) { |
| for (auto& nhA : nhAA) { |
| for (auto& handle : nhA) { |
| native_handle_delete(handle); |
| } |
| } |
| } |
| return Void(); |
| } |
| |
| Return<int32_t> TWGraphicBufferProducer::detachBuffer(int32_t slot) { |
| return static_cast<int32_t>(mBase->detachBuffer(slot)); |
| } |
| |
| Return<void> TWGraphicBufferProducer::detachNextBuffer( |
| detachNextBuffer_cb _hidl_cb) { |
| sp<GraphicBuffer> outBuffer; |
| sp<Fence> outFence; |
| status_t status = mBase->detachNextBuffer(&outBuffer, &outFence); |
| AnwBuffer tBuffer; |
| hidl_handle tFence; |
| |
| if (outBuffer == nullptr) { |
| LOG(ERROR) << "TWGraphicBufferProducer::detachNextBuffer - " |
| "Invalid output buffer"; |
| _hidl_cb(static_cast<int32_t>(status), tBuffer, tFence); |
| return Void(); |
| } |
| wrapAs(&tBuffer, *outBuffer); |
| native_handle_t* nh = nullptr; |
| if ((outFence != nullptr) && !wrapAs(&tFence, &nh, *outFence)) { |
| LOG(ERROR) << "TWGraphicBufferProducer::detachNextBuffer - " |
| "Invalid output fence"; |
| _hidl_cb(static_cast<int32_t>(status), tBuffer, tFence); |
| return Void(); |
| } |
| |
| _hidl_cb(static_cast<int32_t>(status), tBuffer, tFence); |
| native_handle_delete(nh); |
| return Void(); |
| } |
| |
| Return<void> TWGraphicBufferProducer::attachBuffer( |
| const AnwBuffer& buffer, |
| attachBuffer_cb _hidl_cb) { |
| int outSlot; |
| sp<GraphicBuffer> lBuffer = new GraphicBuffer(); |
| if (!convertTo(lBuffer.get(), buffer)) { |
| LOG(ERROR) << "TWGraphicBufferProducer::attachBuffer - " |
| "Invalid input native window buffer"; |
| _hidl_cb(static_cast<int32_t>(BAD_VALUE), -1); |
| return Void(); |
| } |
| status_t status = mBase->attachBuffer(&outSlot, lBuffer); |
| |
| _hidl_cb(static_cast<int32_t>(status), static_cast<int32_t>(outSlot)); |
| return Void(); |
| } |
| |
| Return<void> TWGraphicBufferProducer::queueBuffer( |
| int32_t slot, const QueueBufferInput& input, |
| queueBuffer_cb _hidl_cb) { |
| QueueBufferOutput tOutput; |
| BGraphicBufferProducer::QueueBufferInput lInput( |
| 0, false, HAL_DATASPACE_UNKNOWN, |
| ::android::Rect(0, 0, 1, 1), |
| NATIVE_WINDOW_SCALING_MODE_FREEZE, |
| 0, ::android::Fence::NO_FENCE); |
| if (!convertTo(&lInput, input)) { |
| LOG(ERROR) << "TWGraphicBufferProducer::queueBuffer - " |
| "Invalid input"; |
| _hidl_cb(static_cast<int32_t>(BAD_VALUE), tOutput); |
| return Void(); |
| } |
| BGraphicBufferProducer::QueueBufferOutput lOutput; |
| status_t status = mBase->queueBuffer( |
| static_cast<int>(slot), lInput, &lOutput); |
| |
| std::vector<std::vector<native_handle_t*> > nhAA; |
| if (!wrapAs(&tOutput, &nhAA, lOutput)) { |
| LOG(ERROR) << "TWGraphicBufferProducer::queueBuffer - " |
| "Invalid output"; |
| _hidl_cb(static_cast<int32_t>(BAD_VALUE), tOutput); |
| return Void(); |
| } |
| |
| _hidl_cb(static_cast<int32_t>(status), tOutput); |
| for (auto& nhA : nhAA) { |
| for (auto& nh : nhA) { |
| native_handle_delete(nh); |
| } |
| } |
| return Void(); |
| } |
| |
| Return<int32_t> TWGraphicBufferProducer::cancelBuffer( |
| int32_t slot, const hidl_handle& fence) { |
| sp<Fence> lFence = new Fence(); |
| if (!convertTo(lFence.get(), fence)) { |
| LOG(ERROR) << "TWGraphicBufferProducer::cancelBuffer - " |
| "Invalid input fence"; |
| return static_cast<int32_t>(BAD_VALUE); |
| } |
| return static_cast<int32_t>(mBase->cancelBuffer(static_cast<int>(slot), lFence)); |
| } |
| |
| Return<void> TWGraphicBufferProducer::query(int32_t what, query_cb _hidl_cb) { |
| int lValue; |
| int lReturn = mBase->query(static_cast<int>(what), &lValue); |
| _hidl_cb(static_cast<int32_t>(lReturn), static_cast<int32_t>(lValue)); |
| return Void(); |
| } |
| |
| Return<void> TWGraphicBufferProducer::connect( |
| const sp<HProducerListener>& listener, |
| int32_t api, bool producerControlledByApp, connect_cb _hidl_cb) { |
| sp<BProducerListener> lListener = listener == nullptr ? |
| nullptr : new LWProducerListener(listener); |
| BGraphicBufferProducer::QueueBufferOutput lOutput; |
| status_t status = mBase->connect(lListener, |
| static_cast<int>(api), |
| producerControlledByApp, |
| &lOutput); |
| |
| QueueBufferOutput tOutput; |
| std::vector<std::vector<native_handle_t*> > nhAA; |
| if (!wrapAs(&tOutput, &nhAA, lOutput)) { |
| LOG(ERROR) << "TWGraphicBufferProducer::connect - " |
| "Invalid output"; |
| _hidl_cb(static_cast<int32_t>(status), tOutput); |
| return Void(); |
| } |
| |
| _hidl_cb(static_cast<int32_t>(status), tOutput); |
| for (auto& nhA : nhAA) { |
| for (auto& nh : nhA) { |
| native_handle_delete(nh); |
| } |
| } |
| return Void(); |
| } |
| |
| Return<int32_t> TWGraphicBufferProducer::disconnect( |
| int32_t api, DisconnectMode mode) { |
| return static_cast<int32_t>(mBase->disconnect( |
| static_cast<int>(api), |
| toGuiDisconnectMode(mode))); |
| } |
| |
| Return<int32_t> TWGraphicBufferProducer::setSidebandStream(const hidl_handle& stream) { |
| return static_cast<int32_t>(mBase->setSidebandStream(NativeHandle::create( |
| stream ? native_handle_clone(stream) : NULL, true))); |
| } |
| |
| Return<void> TWGraphicBufferProducer::allocateBuffers( |
| uint32_t width, uint32_t height, PixelFormat format, uint32_t usage) { |
| mBase->allocateBuffers( |
| width, height, |
| static_cast<::android::PixelFormat>(format), |
| usage); |
| return Void(); |
| } |
| |
| Return<int32_t> TWGraphicBufferProducer::allowAllocation(bool allow) { |
| return static_cast<int32_t>(mBase->allowAllocation(allow)); |
| } |
| |
| Return<int32_t> TWGraphicBufferProducer::setGenerationNumber(uint32_t generationNumber) { |
| return static_cast<int32_t>(mBase->setGenerationNumber(generationNumber)); |
| } |
| |
| Return<void> TWGraphicBufferProducer::getConsumerName(getConsumerName_cb _hidl_cb) { |
| _hidl_cb(mBase->getConsumerName().string()); |
| return Void(); |
| } |
| |
| Return<int32_t> TWGraphicBufferProducer::setSharedBufferMode(bool sharedBufferMode) { |
| return static_cast<int32_t>(mBase->setSharedBufferMode(sharedBufferMode)); |
| } |
| |
| Return<int32_t> TWGraphicBufferProducer::setAutoRefresh(bool autoRefresh) { |
| return static_cast<int32_t>(mBase->setAutoRefresh(autoRefresh)); |
| } |
| |
| Return<int32_t> TWGraphicBufferProducer::setDequeueTimeout(int64_t timeoutNs) { |
| return static_cast<int32_t>(mBase->setDequeueTimeout(timeoutNs)); |
| } |
| |
| Return<void> TWGraphicBufferProducer::getLastQueuedBuffer( |
| getLastQueuedBuffer_cb _hidl_cb) { |
| sp<GraphicBuffer> lOutBuffer = new GraphicBuffer(); |
| sp<Fence> lOutFence = new Fence(); |
| float lOutTransformMatrix[16]; |
| status_t status = mBase->getLastQueuedBuffer( |
| &lOutBuffer, &lOutFence, lOutTransformMatrix); |
| |
| AnwBuffer tOutBuffer; |
| if (lOutBuffer != nullptr) { |
| wrapAs(&tOutBuffer, *lOutBuffer); |
| } |
| hidl_handle tOutFence; |
| native_handle_t* nh = nullptr; |
| if ((lOutFence == nullptr) || !wrapAs(&tOutFence, &nh, *lOutFence)) { |
| LOG(ERROR) << "TWGraphicBufferProducer::getLastQueuedBuffer - " |
| "Invalid output fence"; |
| _hidl_cb(static_cast<int32_t>(status), |
| tOutBuffer, |
| tOutFence, |
| hidl_array<float, 16>()); |
| return Void(); |
| } |
| hidl_array<float, 16> tOutTransformMatrix(lOutTransformMatrix); |
| |
| _hidl_cb(static_cast<int32_t>(status), tOutBuffer, tOutFence, tOutTransformMatrix); |
| native_handle_delete(nh); |
| return Void(); |
| } |
| |
| Return<void> TWGraphicBufferProducer::getFrameTimestamps( |
| getFrameTimestamps_cb _hidl_cb) { |
| ::android::FrameEventHistoryDelta lDelta; |
| mBase->getFrameTimestamps(&lDelta); |
| |
| FrameEventHistoryDelta tDelta; |
| std::vector<std::vector<native_handle_t*> > nhAA; |
| if (!wrapAs(&tDelta, &nhAA, lDelta)) { |
| LOG(ERROR) << "TWGraphicBufferProducer::getFrameTimestamps - " |
| "Invalid output frame timestamps"; |
| _hidl_cb(tDelta); |
| return Void(); |
| } |
| |
| _hidl_cb(tDelta); |
| for (auto& nhA : nhAA) { |
| for (auto& nh : nhA) { |
| native_handle_delete(nh); |
| } |
| } |
| return Void(); |
| } |
| |
| Return<void> TWGraphicBufferProducer::getUniqueId(getUniqueId_cb _hidl_cb) { |
| uint64_t outId; |
| status_t status = mBase->getUniqueId(&outId); |
| _hidl_cb(static_cast<int32_t>(status), outId); |
| return Void(); |
| } |
| |
| } // namespace implementation |
| } // namespace V1_0 |
| } // namespace omx |
| } // namespace media |
| } // namespace hardware |
| } // namespace android |