blob: 7f8ba5dcb741464326ff469098d801991bb0789d [file] [log] [blame]
/*
* Copyright Samsung Electronics Co.,LTD.
* Copyright (C) 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.
*/
#include <log/log.h>
#include <ExynosGraphicBuffer.h>
#include <VendorVideoAPI.h>
#include <sync/sync.h>
#include <hardware/exynos/sbwcwrapper.h>
#include "sbwcwrapper_common.h"
#include "sbwcwrapper_mscl.h"
#ifdef LIBSBWC_DPU_ENABLED
#include <hardware/exynos/sbwcdecoder_dpu.h>
#else
#include <sbwcdecoder_dpu_default.h>
#endif
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
#include <utils/Trace.h>
enum decodeIP_t {
DECODE_IP_ERR = 0,
DECODE_IP_MSCL = 1,
DECODE_IP_DPU = 2,
};
SbwcDecoderIP::SbwcDecoderIP(int decodeIPType) : mDecodeIPType(decodeIPType){
switch (decodeIPType) {
case DECODE_IP_DPU:
mHandleIP = new DpuSbwcDecoder();
break;
case DECODE_IP_MSCL:
mHandleIP = new SbwcAcrylInfo();
break;
default:
ALOGE("failed to create SbwcDecoder type %d", decodeIPType);
mHandleIP = NULL;
break;
}
}
SbwcDecoderIP::~SbwcDecoderIP() {
switch (mDecodeIPType) {
case DECODE_IP_DPU:
delete static_cast<DpuSbwcDecoder*>(mHandleIP);
break;
case DECODE_IP_MSCL:
delete static_cast<SbwcAcrylInfo*>(mHandleIP);
break;
default:
ALOGE("failed to remove SbwcDecoder type %d", mDecodeIPType);
break;
}
}
/*
* If new project has a new priority to request decompression to SBWC,
* add here about that. And by using BoardConfig, use something appropriate to project.
*/
static struct sbwcDecoderInfo {
const char *name;
int len;
decodeIP_t type;
} arrDecoderInfo[] = {
{ "Dpu", 3, DECODE_IP_DPU },
{ "Mscl", 4, DECODE_IP_MSCL },
};
bool SbwcWrapper::initSbwcDecoder(void)
{
const char *priority = LIBSBWC_DECODER_PRIORITY;
unsigned int i;
while (*priority != '\0') {
for (i = 0; i < ARRSIZE(arrDecoderInfo); i++) {
if (strncmp(priority, arrDecoderInfo[i].name, arrDecoderInfo[i].len) == 0) {
mVecSbwcDecoderIP.emplace_back(arrDecoderInfo[i].type);
priority += arrDecoderInfo[i].len;
break;
}
}
if (i == ARRSIZE(arrDecoderInfo)) {
ALOGE("failed to get SbwcDecoderPriority of '%s'", LIBSBWC_DECODER_PRIORITY);
return false;
}
}
return true;
}
SbwcWrapper::SbwcWrapper()
{
ATRACE_CALL();
initSbwcDecoder();
}
SbwcWrapper::~SbwcWrapper()
{
ATRACE_CALL();
}
static bool decodeDPU(void *decoderHandle, buffer_handle_t srcBH, buffer_handle_t dstBH, unsigned int attr,
unsigned int cropWidth, unsigned int cropHeight)
{
ATRACE_CALL();
auto *SbwcDecoderDPU = static_cast<DpuSbwcDecoder*>(decoderHandle);
if (!SbwcDecoderDPU)
return false;
int srcFmt;
srcFmt = getFormatFromVideoMeta(srcBH);
if (!srcFmt)
srcFmt = ExynosGraphicBufferMeta::get_internal_format(srcBH);
else if (srcFmt < 0)
return false;
int dstFmt;
dstFmt = getFormatFromVideoMeta(dstBH);
if (!dstFmt)
dstFmt = ExynosGraphicBufferMeta::get_internal_format(dstBH);
else if (dstFmt < 0)
return false;
int srcBuf[3], dstBuf[3];
size_t srcLen[3], dstLen[3];
int dataspace = ExynosGraphicBufferMeta::get_dataspace(srcBH);
for (int i = 0; i < 3; i++) {
srcBuf[i] = ExynosGraphicBufferMeta::get_fd(srcBH, i);
srcLen[i] = ExynosGraphicBufferMeta::get_size(srcBH, i);
dstBuf[i] = ExynosGraphicBufferMeta::get_fd(dstBH, i);
dstLen[i] = ExynosGraphicBufferMeta::get_size(dstBH, i);
}
if (!SbwcDecoderDPU->decodeSBWC(srcFmt, dstFmt, dataspace,
cropWidth, cropHeight,
ExynosGraphicBufferMeta::get_width(dstBH), ExynosGraphicBufferMeta::get_height(dstBH),
ExynosGraphicBufferMeta::get_stride(srcBH), ExynosGraphicBufferMeta::get_stride(dstBH),
attr, srcBuf, dstBuf)) {
return false;
}
return true;
}
bool SbwcWrapper::decode(void *srcHandle, void *dstHandle, unsigned int attr, unsigned int framerate)
{
auto *srcBH = static_cast<buffer_handle_t>(srcHandle);
if (!srcBH)
return false;
return decode(srcHandle, dstHandle, attr, static_cast<unsigned int>(ExynosGraphicBufferMeta::get_width(srcBH)),
static_cast<unsigned int>(ExynosGraphicBufferMeta::get_height(srcBH)), framerate);
}
bool SbwcWrapper::decode(void *srcHandle, void *dstHandle, unsigned int attr, unsigned int cropWidth, unsigned int cropHeight, unsigned int framerate)
{
ATRACE_CALL();
auto *srcBH = static_cast<buffer_handle_t>(srcHandle);
if (!srcBH)
return false;
auto *dstBH = static_cast<buffer_handle_t>(dstHandle);
if (!dstBH)
return false;
for(auto &decoderIP : mVecSbwcDecoderIP) {
bool ret = false;
switch (decoderIP.mDecodeIPType) {
case DECODE_IP_DPU:
ret = decodeDPU(decoderIP.mHandleIP, srcBH, dstBH, attr, cropWidth, cropHeight);
break;
case DECODE_IP_MSCL:
ret = decodeMSCL(decoderIP.mHandleIP, srcBH, dstBH, attr, cropWidth, cropHeight, framerate);
break;
default:
ALOGE("invalid name for sbwc decompress IP type %d", decoderIP.mDecodeIPType);
ret = false;
break;
}
if (ret)
return ret;
}
ALOGE("failed to decompress SBWC");
return false;
}