You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

290 lines
9.4 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/*
* Copyright (c) Hisilicon Technologies Co., Ltd.. 2019-2019. All rights reserved.
* Description: support private media overlay solution
* Author: Hisilicon
* Created: 2019.12.30
*/
#include "TvGraphics.h"
#include <utils/RefBase.h>
#include <log/log.h>
#include <vendor/huanglong/hardware/hwgraphics/1.2/IGraphics.h>
namespace V1_0= vendor::huanglong::hardware::hwgraphics::V1_0;
namespace V1_2= vendor::huanglong::hardware::hwgraphics::V1_2;
using V1_0::CaptureType;
using V1_0::HwRect;
using V1_0::HwLayer;
using namespace android;
namespace {
const int SUCCESS = 0;
const int ERROR = -1;
const int INVALID_FENCE_FD = -1;
const int CAPTURE_MODE_VIDEO = 0;
const int CAPTURE_MODE_VIDEO_GRAPHIC = 2;
const int SET_OVERLAY_FAIL = -1;
android::sp<V1_0::IGraphics> g_tvGraphics = nullptr;
android::sp<V1_2::IGraphics> g_tvGraphics_1_2 = nullptr;
android::sp<HwGraphicsListener> g_hwListener = nullptr;
}
int Init()
{
g_tvGraphics = V1_0::IGraphics::getService();
if (g_tvGraphics == nullptr) {
ALOGE("Can't find TVGraphics Service");
return ERROR;
} else {
// hwgraphic will close all overlay
CloseOverlay(-1);
auto castResult = V1_2::IGraphics::castFrom(g_tvGraphics);
if (castResult.isOk()) {
g_tvGraphics_1_2 = castResult;
if (g_tvGraphics_1_2 != nullptr) {
ALOGI("tvGraphics_1_2 will been used");
}
}
}
return SUCCESS;
}
int PresentOverlay(uint64_t display, int32_t seq, buffer_handle_t handle, bool visible)
{
if (g_tvGraphics == nullptr) {
ALOGE("PresentOverlay failed: Can't find TVGraphics Service");
return ERROR;
}
HwLayer layer = {display, seq, handle};
int releaseFenceFd = INVALID_FENCE_FD;
// present overlay
auto ret = g_tvGraphics->PresentOverlay(layer, visible,
[&releaseFenceFd](const auto& ret, const auto& fenceHandle) mutable {
if (ret != android::NO_ERROR || !fenceHandle) {
return;
}
auto fenceNativeHandle = fenceHandle.getNativeHandle();
if (!fenceNativeHandle || fenceNativeHandle->numFds != 1) {
ALOGE("invalid fence handle");
return;
}
int fenceFd = fenceNativeHandle->data[0];
if (fenceFd >= 0) {
releaseFenceFd = dup(fenceFd);
if (releaseFenceFd < 0) {
ALOGE("No resource during dup fenceFd");
releaseFenceFd = INVALID_FENCE_FD;
return;
}
}
});
if (!ret.isOk()) {
ALOGE("%s failed: HIDL call failed description: %s", __FUNCTION__, ret.description().c_str());
return INVALID_FENCE_FD;
}
return releaseFenceFd;
}
int SetOverlayPosition(int32_t seq, int32_t left, int32_t top, int32_t right, int32_t bottom)
{
if (g_tvGraphics == nullptr) {
ALOGE("SetOverlayPosition failed: Can't find TVGraphics Service");
return SET_OVERLAY_FAIL;
}
HwRect displayFrame = { left, top, right, bottom };
auto ret = g_tvGraphics->SetOverlayPosition(seq, displayFrame);
if (!ret.isOk()) {
ALOGE("%s failed: HIDL call failed description: %s", __FUNCTION__, ret.description().c_str());
}
return ret;
}
int SetOverlayCrop(int32_t seq, int32_t left, int32_t top, int32_t right, int32_t bottom)
{
if (g_tvGraphics == nullptr) {
ALOGE("SetOverlayCrop failed: Can't find TVGraphics Service");
return SET_OVERLAY_FAIL;
}
HwRect sourceCrop = { left, top, right, bottom };
auto ret = g_tvGraphics->SetOverlayCrop(seq, sourceCrop);
if (!ret.isOk()) {
ALOGE("%s failed: HIDL call failed description: %s", __FUNCTION__, ret.description().c_str());
}
return ret;
}
int SetOverlayTransform(int32_t seq, int32_t transform)
{
if (g_tvGraphics == nullptr) {
ALOGE("SetOverlayTransform failed: Can't find TVGraphics Service");
return SET_OVERLAY_FAIL;
}
auto ret = g_tvGraphics->SetOverlayTransform(seq, transform);
if (!ret.isOk()) {
ALOGE("%s failed: HIDL call failed description: %s", __FUNCTION__, ret.description().c_str());
}
return ret;
}
int SetOverlayZOrder(int32_t seq, int32_t zOrder)
{
if (g_tvGraphics_1_2 == nullptr) {
ALOGE("SetOverlayZOrder failed: Can't find TVGraphics Service");
return SET_OVERLAY_FAIL;
}
auto ret = g_tvGraphics_1_2->SetOverlayZOrder(seq, zOrder);
if (!ret.isOk()) {
ALOGE("%s failed: HIDL call failed description: %s", __FUNCTION__, ret.description().c_str());
}
return ret;
}
void SetOverlayDataSpace(int32_t seq, int32_t dataSpace)
{
if (g_tvGraphics_1_2 != nullptr) {
auto ret = g_tvGraphics_1_2->SetOverlayDataSpace(seq, dataSpace);
if (!ret.isOk()) {
ALOGE("%s failed: HIDL call failed description: %s", __FUNCTION__, ret.description().c_str());
return;
}
} else {
ALOGE("only Graphics_1_2 can support set overlay layer dataSpace");
}
}
void CloseOverlay(int32_t seq)
{
if (g_tvGraphics == nullptr) {
ALOGE("CloseOverlay failed: Can't find TVGraphics Service");
return;
}
auto ret = g_tvGraphics->CloseOverlay(seq);
if (!ret.isOk()) {
ALOGE("%s failed: HIDL call failed description: %s", __FUNCTION__, ret.description().c_str());
}
}
int InitCast(uint64_t display, uint32_t format, uint32_t width, uint32_t height)
{
if (g_tvGraphics_1_2 == nullptr) {
ALOGE("InitCast failed: Can't find TVGraphics Service");
return ERROR;
}
return g_tvGraphics_1_2->InitCast(display, format, width, height);
}
int CastFrame(int32_t castHandle, const buffer_handle_t& rawHandle, const buffer_handle_t& fence,
int& acqurieFence)
{
if (g_tvGraphics_1_2 == nullptr) {
ALOGE("CastFrame failed: Can't find TVGraphics Service");
return ERROR;
}
int result = -1;
auto ret = g_tvGraphics_1_2->CastFrame(castHandle, rawHandle, fence,
[&result, &acqurieFence](const auto& ret, const auto& fenceHandle) mutable {
result = ret;
if (ret != SUCCESS || !fenceHandle) {
return;
}
auto handle = fenceHandle.getNativeHandle();
if (!handle || handle->numFds != 1) {
ALOGE("invalid fence handle");
return;
}
int fenceFd = handle->data[0];
if (fenceFd >= 0) {
acqurieFence = dup(fenceFd);
if (acqurieFence < 0) {
ALOGE("No resource during dup fenceFd");
acqurieFence = -1;
return;
}
}
});
if (!ret.isOk()) {
ALOGE("%s failed: HIDL call failed description: %s", __FUNCTION__, ret.description().c_str());
}
return result;
}
int CloseCast(int32_t castHandle)
{
if (g_tvGraphics_1_2 == nullptr) {
ALOGE("CloseCast failed: Can't find TVGraphics Service");
return ERROR;
}
return g_tvGraphics_1_2->CloseCast(castHandle);
}
void SetBlackCastFrame(bool isBlack)
{
if (g_tvGraphics_1_2 == nullptr) {
ALOGE("SetBlackCastFrame failed: Can't find TVGraphics Service");
return;
}
auto ret = g_tvGraphics_1_2->SetBlackCastFrame(isBlack);
if (!ret.isOk()) {
ALOGE("%s failed: HIDL call failed description: %s", __FUNCTION__, ret.description().c_str());
}
}
int CaptureScreenByVDP(int32_t mode, buffer_handle_t buffer, ARect cropRect)
{
if (g_tvGraphics == nullptr) {
ALOGE("CaptureScreenByVDP failed: Can't find TVGraphics Service");
return ERROR;
}
CaptureType captureType;
if (mode == CAPTURE_MODE_VIDEO) {
captureType = CaptureType::CAPTURE_TYPE_VIDEO;
} else if (mode == CAPTURE_MODE_VIDEO_GRAPHIC) {
captureType = CaptureType::CAPTURE_TYPE_VIDEO_GRAPHIC;
} else {
ALOGI("captureMode:%d, should use aosp solution", mode);
return ERROR;
}
ALOGI("CaptureScreenByVDP mode:%d", mode);
android::hardware::Return<uint32_t> ret = 0;
auto castResult = V1_2::IGraphics::castFrom(g_tvGraphics);
if (castResult.isOk()) {
android::sp<V1_2::IGraphics> tvGraphics_1_2 = castResult;
if (tvGraphics_1_2 != nullptr) {
HwRect rect = {cropRect.left, cropRect.top, cropRect.right, cropRect.bottom};
ALOGI("CaptureScreenByVDP_1_2 crop:[%d, %d, %d, %d]", rect.left, rect.top, rect.right, rect.bottom);
ret = tvGraphics_1_2->CaptureScreenByVDP_1_2(captureType, buffer, rect);
} else {
ret = g_tvGraphics->CaptureScreenByVDP(captureType, buffer);
}
if (!ret.isOk()) {
ALOGE("%s failed: HIDL call failed description: %s", __FUNCTION__, ret.description().c_str());
return ERROR;
}
}
if (!castResult.isOk()) {
ALOGE("%s failed: HIDL call failed description: %s", __FUNCTION__, ret.description().c_str());
return ERROR;
}
ALOGI("Capture mode:%d successret = %s", mode, ret.description().c_str());
return ret;
}
void SfDeathRecipient()
{
if (g_tvGraphics_1_2 == nullptr) {
ALOGE("sfDeathRecipient failed: Can't find TVGraphics Service");
return;
}
if (g_hwListener == nullptr) {
g_hwListener = new HwGraphicsListener();
}
auto ret = g_tvGraphics_1_2->SfDeathRecipient(g_hwListener);
if (!ret.isOk()) {
ALOGE("sfDeathRecipient failed: %s", ret.description().c_str());
}
}