blob: 8ddf20f94264c0ce6bf0abfad91b0c2e6c559142 [file] [log] [blame]
/*
* 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.
*/
#ifndef MEDIA_STAGEFRIGHT_WGRAPHICBUFFERPRODUCER_H_
#define MEDIA_STAGEFRIGHT_WGRAPHICBUFFERPRODUCER_H_
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>
#include <binder/Binder.h>
#include <gui/IGraphicBufferProducer.h>
#include <gui/IProducerListener.h>
#include <media/stagefright/bqhelper/Conversion.h>
#include <media/stagefright/bqhelper/WProducerListener.h>
#include <system/window.h>
#include <android/hardware/graphics/bufferqueue/1.0/IGraphicBufferProducer.h>
namespace android {
using ::android::hardware::media::V1_0::AnwBuffer;
using ::android::hidl::base::V1_0::IBase;
using ::android::hardware::hidl_array;
using ::android::hardware::hidl_handle;
using ::android::hardware::hidl_memory;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::sp;
typedef ::android::hardware::graphics::bufferqueue::V1_0::
IGraphicBufferProducer HGraphicBufferProducer;
typedef ::android::hardware::graphics::bufferqueue::V1_0::
IProducerListener HProducerListener;
typedef ::android::IGraphicBufferProducer BGraphicBufferProducer;
typedef ::android::IProducerListener BProducerListener;
using ::android::BnGraphicBufferProducer;
#ifndef LOG
struct LOG_dummy {
template <typename T>
LOG_dummy& operator<< (const T&) { return *this; }
};
#define LOG(x) LOG_dummy()
#endif
// Instantiate only if HGraphicBufferProducer is base of BASE.
template <typename BASE,
typename = typename std::enable_if<std::is_base_of<HGraphicBufferProducer, BASE>::value>::type>
struct TWGraphicBufferProducer : public BASE {
TWGraphicBufferProducer(sp<BGraphicBufferProducer> const& base) : mBase(base) {}
Return<void> requestBuffer(int32_t slot, HGraphicBufferProducer::requestBuffer_cb _hidl_cb) override {
sp<GraphicBuffer> buf;
status_t status = mBase->requestBuffer(slot, &buf);
AnwBuffer anwBuffer;
if (buf != nullptr) {
::android::conversion::wrapAs(&anwBuffer, *buf);
}
_hidl_cb(static_cast<int32_t>(status), anwBuffer);
return Void();
}
Return<int32_t> setMaxDequeuedBufferCount(int32_t maxDequeuedBuffers) override {
return static_cast<int32_t>(mBase->setMaxDequeuedBufferCount(
static_cast<int>(maxDequeuedBuffers)));
}
Return<int32_t> setAsyncMode(bool async) override {
return static_cast<int32_t>(mBase->setAsyncMode(async));
}
Return<void> dequeueBuffer(
uint32_t width, uint32_t height,
::android::hardware::graphics::common::V1_0::PixelFormat format, uint32_t usage,
bool getFrameTimestamps, HGraphicBufferProducer::dequeueBuffer_cb _hidl_cb) override {
int slot;
sp<Fence> fence;
::android::FrameEventHistoryDelta outTimestamps;
status_t status = mBase->dequeueBuffer(
&slot, &fence, width, height,
static_cast<::android::PixelFormat>(format), usage, nullptr,
getFrameTimestamps ? &outTimestamps : nullptr);
hidl_handle tFence;
HGraphicBufferProducer::FrameEventHistoryDelta tOutTimestamps;
native_handle_t* nh = nullptr;
if ((fence == nullptr) || !::android::conversion::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 && !::android::conversion::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> detachBuffer(int32_t slot) override {
return static_cast<int32_t>(mBase->detachBuffer(slot));
}
Return<void> detachNextBuffer(HGraphicBufferProducer::detachNextBuffer_cb _hidl_cb) override {
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();
}
::android::conversion::wrapAs(&tBuffer, *outBuffer);
native_handle_t* nh = nullptr;
if ((outFence != nullptr) && !::android::conversion::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> attachBuffer(const AnwBuffer& buffer, HGraphicBufferProducer::attachBuffer_cb _hidl_cb) override {
int outSlot;
sp<GraphicBuffer> lBuffer = new GraphicBuffer();
if (!::android::conversion::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> queueBuffer(
int32_t slot, const HGraphicBufferProducer::QueueBufferInput& input,
HGraphicBufferProducer::queueBuffer_cb _hidl_cb) override {
HGraphicBufferProducer::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 (!::android::conversion::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 (!::android::conversion::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> cancelBuffer(int32_t slot, const hidl_handle& fence) override {
sp<Fence> lFence = new Fence();
if (!::android::conversion::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> query(int32_t what, HGraphicBufferProducer::query_cb _hidl_cb) override {
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> connect(const sp<HProducerListener>& listener,
int32_t api, bool producerControlledByApp,
HGraphicBufferProducer::connect_cb _hidl_cb) override {
sp<BProducerListener> lListener = listener == nullptr ?
nullptr : new LWProducerListener(listener);
BGraphicBufferProducer::QueueBufferOutput lOutput;
status_t status = mBase->connect(lListener,
static_cast<int>(api),
producerControlledByApp,
&lOutput);
HGraphicBufferProducer::QueueBufferOutput tOutput;
std::vector<std::vector<native_handle_t*> > nhAA;
if (!::android::conversion::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> disconnect(
int32_t api,
HGraphicBufferProducer::DisconnectMode mode) override {
return static_cast<int32_t>(mBase->disconnect(
static_cast<int>(api),
::android::conversion::toGuiDisconnectMode(mode)));
}
Return<int32_t> setSidebandStream(const hidl_handle& stream) override {
return static_cast<int32_t>(mBase->setSidebandStream(NativeHandle::create(
stream ? native_handle_clone(stream) : NULL, true)));
}
Return<void> allocateBuffers(
uint32_t width, uint32_t height,
::android::hardware::graphics::common::V1_0::PixelFormat format,
uint32_t usage) override {
mBase->allocateBuffers(
width, height,
static_cast<::android::PixelFormat>(format),
usage);
return Void();
}
Return<int32_t> allowAllocation(bool allow) override {
return static_cast<int32_t>(mBase->allowAllocation(allow));
}
Return<int32_t> setGenerationNumber(uint32_t generationNumber) override {
return static_cast<int32_t>(mBase->setGenerationNumber(generationNumber));
}
Return<void> getConsumerName(HGraphicBufferProducer::getConsumerName_cb _hidl_cb) override {
_hidl_cb(mBase->getConsumerName().string());
return Void();
}
Return<int32_t> setSharedBufferMode(bool sharedBufferMode) override {
return static_cast<int32_t>(mBase->setSharedBufferMode(sharedBufferMode));
}
Return<int32_t> setAutoRefresh(bool autoRefresh) override {
return static_cast<int32_t>(mBase->setAutoRefresh(autoRefresh));
}
Return<int32_t> setDequeueTimeout(int64_t timeoutNs) override {
return static_cast<int32_t>(mBase->setDequeueTimeout(timeoutNs));
}
Return<void> getLastQueuedBuffer(HGraphicBufferProducer::getLastQueuedBuffer_cb _hidl_cb) override {
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) {
::android::conversion::wrapAs(&tOutBuffer, *lOutBuffer);
}
hidl_handle tOutFence;
native_handle_t* nh = nullptr;
if ((lOutFence == nullptr) || !::android::conversion::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> getFrameTimestamps(HGraphicBufferProducer::getFrameTimestamps_cb _hidl_cb) override {
::android::FrameEventHistoryDelta lDelta;
mBase->getFrameTimestamps(&lDelta);
HGraphicBufferProducer::FrameEventHistoryDelta tDelta;
std::vector<std::vector<native_handle_t*> > nhAA;
if (!::android::conversion::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> getUniqueId(HGraphicBufferProducer::getUniqueId_cb _hidl_cb) override {
uint64_t outId;
status_t status = mBase->getUniqueId(&outId);
_hidl_cb(static_cast<int32_t>(status), outId);
return Void();
}
private:
sp<BGraphicBufferProducer> mBase;
};
} // namespace android
#endif // MEDIA_STAGEFRIGHT_WGRAPHICBUFFERPRODUCER_H_