275 lines
12 KiB
C++
275 lines
12 KiB
C++
|
|
/*
|
||
|
|
* Copyright(C) 2020. Huawei Technologies Co.,Ltd. All rights reserved.
|
||
|
|
*
|
||
|
|
* 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 "DvppCommonDevice.h"
|
||
|
|
#include "ErrorCode.h"
|
||
|
|
#include "Log.h"
|
||
|
|
|
||
|
|
APP_ERROR DvppCommonDevice::Init()
|
||
|
|
{
|
||
|
|
iDvppApi_ = nullptr;
|
||
|
|
uint32_t ret = CreateDvppApi(iDvppApi_);
|
||
|
|
if (ret != APP_ERR_OK) {
|
||
|
|
LogError << "create DVPP API fail, ret=" << ret;
|
||
|
|
return APP_ERR_COMM_INIT_FAIL;
|
||
|
|
}
|
||
|
|
return APP_ERR_OK;
|
||
|
|
}
|
||
|
|
|
||
|
|
APP_ERROR DvppCommonDevice::DeInit()
|
||
|
|
{
|
||
|
|
if (iDvppApi_ == nullptr) {
|
||
|
|
LogWarn << "DVPP objet is null";
|
||
|
|
return APP_ERR_COMM_INVALID_POINTER;
|
||
|
|
}
|
||
|
|
uint32_t ret = DestroyDvppApi(iDvppApi_);
|
||
|
|
if (ret != APP_ERR_OK) {
|
||
|
|
LogError << "destroy DVPP API fail, ret=" << ret;
|
||
|
|
return APP_ERR_COMM_FAILURE;
|
||
|
|
}
|
||
|
|
return APP_ERR_OK;
|
||
|
|
}
|
||
|
|
|
||
|
|
APP_ERROR DvppCommonDevice::VpcResize(DvppResizeInputMsg input)
|
||
|
|
{
|
||
|
|
if (input.outBuf == nullptr || input.imgBuf == nullptr) {
|
||
|
|
LogError << "input buffer or output buffer is null, input.imgBuf=" << (void *)input.imgBuf
|
||
|
|
<< ", input.outBuf=" << (void *)input.outBuf;
|
||
|
|
return APP_ERR_COMM_INVALID_POINTER;
|
||
|
|
}
|
||
|
|
uint32_t inWidthStride = DVPP_ALIGN_UP(input.inW, VPC_WIDTH_ALIGN);
|
||
|
|
uint32_t inHeightStride = DVPP_ALIGN_UP(input.inH, VPC_HEIGHT_ALIGN);
|
||
|
|
SetImageConfigure(imageConfigure_, inWidthStride, inHeightStride, input.imgBuf);
|
||
|
|
auto roiConfigure = std::make_shared<struct VpcUserRoiConfigure>();
|
||
|
|
roiConfigure->next = nullptr;
|
||
|
|
struct VpcUserRoiInputConfigure *inputConfigure = &(roiConfigure->inputConfigure);
|
||
|
|
SetCropConfigure(inputConfigure->cropArea, 0, inWidthStride - 1, 0, inHeightStride - 1);
|
||
|
|
|
||
|
|
uint32_t outWidthStride = DVPP_ALIGN_UP(input.outW, VPC_WIDTH_ALIGN);
|
||
|
|
uint32_t outHeightStride = DVPP_ALIGN_UP(input.outH, VPC_HEIGHT_ALIGN);
|
||
|
|
struct VpcUserRoiOutputConfigure *outputConfigure = &(roiConfigure->outputConfigure);
|
||
|
|
SetRoiOutputConfigure(outputConfigure, outWidthStride, outHeightStride, input.outBuf);
|
||
|
|
SetCropConfigure(outputConfigure->outputArea, 0, outWidthStride - 1, 0, outHeightStride - 1);
|
||
|
|
|
||
|
|
imageConfigure_.roiConfigure = roiConfigure.get();
|
||
|
|
|
||
|
|
dvppApiCtrlMsg_.in = static_cast<void *>(&imageConfigure_);
|
||
|
|
dvppApiCtrlMsg_.in_size = sizeof(VpcUserImageConfigure);
|
||
|
|
int ret = DvppCtl(iDvppApi_, DVPP_CTL_VPC_PROC, &dvppApiCtrlMsg_);
|
||
|
|
if (ret != APP_ERR_OK) {
|
||
|
|
LogError << "resize fail, ret=" << ret;
|
||
|
|
return APP_ERR_COMM_FAILURE;
|
||
|
|
}
|
||
|
|
return APP_ERR_OK;
|
||
|
|
}
|
||
|
|
|
||
|
|
APP_ERROR DvppCommonDevice::VpcResizeWithPadding(DvppResizeInputMsg input)
|
||
|
|
{
|
||
|
|
if (input.outBuf == nullptr || input.imgBuf == nullptr) {
|
||
|
|
LogError << "input buffer or output buffer is null, input.imgBuf=" << (void *)input.imgBuf
|
||
|
|
<< ", input.outBuf=" << (void *)input.outBuf;
|
||
|
|
return APP_ERR_COMM_INVALID_POINTER;
|
||
|
|
}
|
||
|
|
uint32_t inWidthStride = DVPP_ALIGN_UP(input.inW, VPC_HEIGHT_ALIGN);
|
||
|
|
uint32_t inHeightStride = DVPP_ALIGN_UP(input.inH, VPC_HEIGHT_ALIGN);
|
||
|
|
uint32_t outWidthStride = DVPP_ALIGN_UP(input.outW, VPC_WIDTH_ALIGN);
|
||
|
|
uint32_t outHeightStride = DVPP_ALIGN_UP(input.outH, VPC_HEIGHT_ALIGN);
|
||
|
|
SetImageConfigure(imageConfigure_, inWidthStride, inHeightStride, input.imgBuf);
|
||
|
|
auto roiConfigure = std::make_shared<struct VpcUserRoiConfigure>();
|
||
|
|
roiConfigure->next = nullptr;
|
||
|
|
struct VpcUserRoiInputConfigure *inputConfigure = &(roiConfigure->inputConfigure);
|
||
|
|
uint32_t upOffset = 0;
|
||
|
|
uint32_t downOffset = inHeightStride - 1;
|
||
|
|
uint32_t leftOffset = 0;
|
||
|
|
uint32_t rightOffset = inWidthStride - 1;
|
||
|
|
SetCropConfigure(inputConfigure->cropArea, leftOffset, rightOffset, upOffset, downOffset);
|
||
|
|
|
||
|
|
struct VpcUserRoiOutputConfigure *outputConfigure = &(roiConfigure->outputConfigure);
|
||
|
|
SetRoiOutputConfigure(outputConfigure, outWidthStride, outHeightStride, input.outBuf);
|
||
|
|
if ((float(inWidthStride) / float(outWidthStride)) >= (float(inHeightStride) / float(outHeightStride))) {
|
||
|
|
float scale = ((float)outWidthStride) / ((float)inWidthStride);
|
||
|
|
downOffset = DVPP_ALIGN_UP(uint32_t(scale * inHeightStride), VPC_OFFSET_ALIGN) - 1;
|
||
|
|
rightOffset = outWidthStride - 1;
|
||
|
|
} else {
|
||
|
|
float scale = ((float)outHeightStride) / ((float)inHeightStride);
|
||
|
|
rightOffset = DVPP_ALIGN_UP(uint32_t(scale * inWidthStride), VPC_OFFSET_ALIGN) - 1;
|
||
|
|
downOffset = outHeightStride - 1;
|
||
|
|
}
|
||
|
|
SetCropConfigure(outputConfigure->outputArea, leftOffset, rightOffset, upOffset, downOffset);
|
||
|
|
|
||
|
|
imageConfigure_.roiConfigure = roiConfigure.get();
|
||
|
|
|
||
|
|
dvppApiCtrlMsg_.in = static_cast<void *>(&imageConfigure_);
|
||
|
|
dvppApiCtrlMsg_.in_size = sizeof(VpcUserImageConfigure);
|
||
|
|
int ret = DvppCtl(iDvppApi_, DVPP_CTL_VPC_PROC, &dvppApiCtrlMsg_);
|
||
|
|
if (ret != APP_ERR_OK) {
|
||
|
|
LogError << "resize fail, ret=" << ret;
|
||
|
|
return APP_ERR_COMM_FAILURE;
|
||
|
|
}
|
||
|
|
return APP_ERR_OK;
|
||
|
|
}
|
||
|
|
|
||
|
|
void DvppCommonDevice::SetImageConfigure(VpcUserImageConfigure &imageConfigure, const uint32_t inWidthStride,
|
||
|
|
const uint32_t inHeightStride, uint8_t *&inBuffer)
|
||
|
|
{
|
||
|
|
imageConfigure.bareDataAddr = inBuffer;
|
||
|
|
imageConfigure.bareDataBufferSize =
|
||
|
|
inWidthStride * inHeightStride * YUV_BGR_SIZE_CONVERT_3 / YUV_BGR_SIZE_CONVERT_2;
|
||
|
|
imageConfigure.isCompressData = false;
|
||
|
|
imageConfigure.widthStride = inWidthStride;
|
||
|
|
imageConfigure.heightStride = inHeightStride;
|
||
|
|
imageConfigure.inputFormat = INPUT_YUV420_SEMI_PLANNER_UV;
|
||
|
|
imageConfigure.outputFormat = OUTPUT_YUV420SP_UV;
|
||
|
|
imageConfigure.yuvSumEnable = false;
|
||
|
|
imageConfigure.cmdListBufferAddr = nullptr;
|
||
|
|
imageConfigure.cmdListBufferSize = 0;
|
||
|
|
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
void DvppCommonDevice::SetCropConfigure(VpcUserCropConfigure &cropArea, const uint32_t leftOffset,
|
||
|
|
const uint32_t rightOffset, const uint32_t upOffset, const uint32_t downOffset)
|
||
|
|
{
|
||
|
|
cropArea.leftOffset = leftOffset;
|
||
|
|
cropArea.rightOffset = rightOffset;
|
||
|
|
cropArea.upOffset = upOffset;
|
||
|
|
cropArea.downOffset = downOffset;
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
void DvppCommonDevice::SetRoiOutputConfigure(VpcUserRoiOutputConfigure *&outputConfigure, const uint32_t outWidthStride,
|
||
|
|
const uint32_t outHeightStride, uint8_t *&outBuffer)
|
||
|
|
{
|
||
|
|
outputConfigure->addr = outBuffer;
|
||
|
|
outputConfigure->bufferSize = outWidthStride * outHeightStride * YUV_BGR_SIZE_CONVERT_3 / YUV_BGR_SIZE_CONVERT_2;
|
||
|
|
outputConfigure->widthStride = outWidthStride;
|
||
|
|
outputConfigure->heightStride = outHeightStride;
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
APP_ERROR DvppCommonDevice::VpcCrop(DvppCropInputMsg input)
|
||
|
|
{
|
||
|
|
uint32_t inWidthStride = DVPP_ALIGN_UP(input.inW, VPC_WIDTH_ALIGN);
|
||
|
|
uint32_t inHeightStride = DVPP_ALIGN_UP(input.inH, VPC_HEIGHT_ALIGN);
|
||
|
|
SetImageConfigure(imageConfigure_, inWidthStride, inHeightStride, input.imgBuf);
|
||
|
|
|
||
|
|
auto roiConfigure = std::make_shared<struct VpcUserRoiConfigure>();
|
||
|
|
roiConfigure->next = nullptr;
|
||
|
|
struct VpcUserRoiInputConfigure *inputConfigure = &(roiConfigure->inputConfigure);
|
||
|
|
uint32_t leftOffset = input.roi.left / VPC_OFFSET_ALIGN * VPC_OFFSET_ALIGN;
|
||
|
|
uint32_t rightOffset = input.roi.right / VPC_OFFSET_ALIGN * VPC_OFFSET_ALIGN - 1;
|
||
|
|
uint32_t upOffset = input.roi.up / VPC_OFFSET_ALIGN * VPC_OFFSET_ALIGN;
|
||
|
|
uint32_t downOffset = input.roi.down / VPC_OFFSET_ALIGN * VPC_OFFSET_ALIGN - 1;
|
||
|
|
SetCropConfigure(inputConfigure->cropArea, leftOffset, rightOffset, upOffset, downOffset);
|
||
|
|
|
||
|
|
uint32_t outWidthStride = DVPP_ALIGN_UP(input.outW, VPC_WIDTH_ALIGN);
|
||
|
|
uint32_t outHeightStride = DVPP_ALIGN_UP(input.outH, VPC_HEIGHT_ALIGN);
|
||
|
|
struct VpcUserRoiOutputConfigure *outputConfigure = &(roiConfigure->outputConfigure);
|
||
|
|
SetRoiOutputConfigure(outputConfigure, outWidthStride, outHeightStride, input.outBuf);
|
||
|
|
SetCropConfigure(outputConfigure->outputArea, 0, outWidthStride - 1, 0, outHeightStride - 1);
|
||
|
|
|
||
|
|
imageConfigure_.roiConfigure = roiConfigure.get();
|
||
|
|
|
||
|
|
dvppApiCtrlMsg_.in = static_cast<void *>(&imageConfigure_);
|
||
|
|
dvppApiCtrlMsg_.in_size = sizeof(VpcUserImageConfigure);
|
||
|
|
int ret = DvppCtl(iDvppApi_, DVPP_CTL_VPC_PROC, &dvppApiCtrlMsg_);
|
||
|
|
if (ret != APP_ERR_OK) {
|
||
|
|
LogError << "resize fail, ret=" << ret;
|
||
|
|
return APP_ERR_COMM_FAILURE;
|
||
|
|
}
|
||
|
|
return APP_ERR_OK;
|
||
|
|
}
|
||
|
|
|
||
|
|
APP_ERROR DvppCommonDevice::VpcMultiCrop(std::vector<DvppCropInputMsg> inputs)
|
||
|
|
{
|
||
|
|
LogDebug << "VpcCrop Count: " << inputs.size();
|
||
|
|
VpcUserRoiConfigure *lastRoi = nullptr;
|
||
|
|
const uint32_t zero = 0;
|
||
|
|
for (unsigned int i = 0; i < inputs.size(); i++) {
|
||
|
|
DvppCropInputMsg input = inputs[i];
|
||
|
|
uint32_t inWidthStride = DVPP_ALIGN_UP(input.inW, VPC_WIDTH_ALIGN);
|
||
|
|
uint32_t inHeightStride = DVPP_ALIGN_UP(input.inH, VPC_HEIGHT_ALIGN);
|
||
|
|
SetImageConfigure(imageConfigure_, inWidthStride, inHeightStride, input.imgBuf);
|
||
|
|
|
||
|
|
// std::shared_ptr<struct VpcUserRoiConfigure> roiConfigure(new VpcUserRoiConfigure);
|
||
|
|
struct VpcUserRoiConfigure *roiConfigure = new VpcUserRoiConfigure();
|
||
|
|
roiConfigure->next = lastRoi;
|
||
|
|
struct VpcUserRoiInputConfigure *inputConfigure = &(roiConfigure->inputConfigure);
|
||
|
|
uint32_t leftOffset = input.roi.left / VPC_OFFSET_ALIGN * VPC_OFFSET_ALIGN;
|
||
|
|
uint32_t rightOffset = input.roi.right / VPC_OFFSET_ALIGN * VPC_OFFSET_ALIGN - 1;
|
||
|
|
uint32_t upOffset = input.roi.up / VPC_OFFSET_ALIGN * VPC_OFFSET_ALIGN;
|
||
|
|
uint32_t downOffset = input.roi.down / VPC_OFFSET_ALIGN * VPC_OFFSET_ALIGN - 1;
|
||
|
|
SetCropConfigure(inputConfigure->cropArea, leftOffset, rightOffset, upOffset, downOffset);
|
||
|
|
|
||
|
|
uint32_t outWidthStride = DVPP_ALIGN_UP(input.outW, VPC_WIDTH_ALIGN);
|
||
|
|
uint32_t outHeightStride = DVPP_ALIGN_UP(input.outH, VPC_HEIGHT_ALIGN);
|
||
|
|
struct VpcUserRoiOutputConfigure *outputConfigure = &(roiConfigure->outputConfigure);
|
||
|
|
SetRoiOutputConfigure(outputConfigure, outWidthStride, outHeightStride, input.outBuf);
|
||
|
|
SetCropConfigure(outputConfigure->outputArea, zero, outWidthStride - 1, zero, outHeightStride - 1);
|
||
|
|
|
||
|
|
lastRoi = roiConfigure;
|
||
|
|
}
|
||
|
|
|
||
|
|
imageConfigure_.roiConfigure = lastRoi;
|
||
|
|
|
||
|
|
dvppApiCtrlMsg_.in = static_cast<void *>(&imageConfigure_);
|
||
|
|
dvppApiCtrlMsg_.in_size = sizeof(VpcUserImageConfigure);
|
||
|
|
int ret = DvppCtl(iDvppApi_, DVPP_CTL_VPC_PROC, &dvppApiCtrlMsg_);
|
||
|
|
|
||
|
|
while (lastRoi != nullptr) {
|
||
|
|
struct VpcUserRoiConfigure *tmp = lastRoi->next;
|
||
|
|
delete lastRoi;
|
||
|
|
lastRoi = tmp;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (ret != APP_ERR_OK) {
|
||
|
|
LogError << "resize fail, ret=" << ret;
|
||
|
|
return APP_ERR_COMM_FAILURE;
|
||
|
|
}
|
||
|
|
return APP_ERR_OK;
|
||
|
|
}
|
||
|
|
|
||
|
|
APP_ERROR DvppCommonDevice::DvppJpegDecode(DvppJpegDecodeInputMsg &input)
|
||
|
|
{
|
||
|
|
// input setting
|
||
|
|
jpegdIn_.jpegData = input.rawBuf;
|
||
|
|
jpegdIn_.isYUV420Need = true;
|
||
|
|
jpegdIn_.jpegDataSize = input.rawBufByteLength + DVPP_JPEG_OFFSET;
|
||
|
|
jpegdIn_.isVBeforeU = false;
|
||
|
|
// output setting
|
||
|
|
uint32_t W_Aligned = DVPP_ALIGN_UP(input.jpegWidth, JPEG_WIDTH_ALIGN);
|
||
|
|
uint32_t H_Aligned = DVPP_ALIGN_UP(input.jpegHeight, JPEG_HEIGHT_ALIGN);
|
||
|
|
uint32_t outputBuffSize = W_Aligned * H_Aligned * YUV_BGR_SIZE_CONVERT_3 / YUV_BGR_SIZE_CONVERT_2;
|
||
|
|
jpegdOut_.yuvData = input.decodedBuf;
|
||
|
|
jpegdOut_.yuvDataSize = outputBuffSize;
|
||
|
|
|
||
|
|
dvppApiCtrlMsg_.in = static_cast<void *>(&jpegdIn_);
|
||
|
|
dvppApiCtrlMsg_.in_size = sizeof(JpegdIn);
|
||
|
|
dvppApiCtrlMsg_.out = static_cast<void *>(&jpegdOut_);
|
||
|
|
dvppApiCtrlMsg_.out_size = sizeof(JpegdOut);
|
||
|
|
uint32_t ret = DvppCtl(iDvppApi_, DVPP_CTL_JPEGD_PROC, &dvppApiCtrlMsg_);
|
||
|
|
if (ret != APP_ERR_OK) {
|
||
|
|
LogError << "decode jpeg fail, ret=" << ret;
|
||
|
|
return APP_ERR_COMM_FAILURE;
|
||
|
|
}
|
||
|
|
return APP_ERR_OK;
|
||
|
|
}
|
||
|
|
|
||
|
|
uint32_t DvppCommonDevice::GetBufferSize(uint32_t w, uint32_t h)
|
||
|
|
{
|
||
|
|
uint32_t widthStride = DVPP_ALIGN_UP(w, VPC_WIDTH_ALIGN);
|
||
|
|
uint32_t heightStride = DVPP_ALIGN_UP(h, VPC_HEIGHT_ALIGN);
|
||
|
|
return widthStride * heightStride * YUV_BGR_SIZE_CONVERT_3 / YUV_BGR_SIZE_CONVERT_2;
|
||
|
|
}
|