android13/hardware/rockchip/tv_input/sideband/RTSidebandWindow.cpp

731 lines
25 KiB
C++

/*
* Copyright 2019 Rockchip Electronics Co. LTD
*
* 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.
*
* author: rimon.xu@rock-chips.com
* date: 2019/12/31
* module: sideband window
*/
//#define LOG_NDEBUG 0
//#define LOG_TAG "RTSidebandWindow"
#include "RTSidebandWindow.h"
#include "log/log.h"
#include <sys/stat.h>
#include <sys/time.h>
#include <utils/Timers.h>
#include <string.h>
#include <ui/GraphicBufferAllocator.h>
#include "DrmVopRender.h"
namespace android {
#define MIN_BUFFER_COUNT_UNDEQUEUE 0
static uint64_t g_session_id;
RTSidebandWindow::RTSidebandWindow()
: mBuffMgr(nullptr),
mVopRender(NULL),
mVTDevFd(-1),
mVTID(-1),
mRenderingCnt(0),
mThreadRunning(false),
mMessageQueue("RenderThread", static_cast<int>(MESSAGE_ID_MAX)),
mMessageThread(nullptr),
mDebugLevel(0) {
memset(&mSidebandInfo, 0, sizeof(mSidebandInfo));
}
RTSidebandWindow::~RTSidebandWindow() {
DEBUG_PRINT(mDebugLevel, "%s %d in", __FUNCTION__, __LINE__);
}
status_t RTSidebandWindow::init(const vt_win_attr_t *attr, int sidebandType) {
ALOGD("%s %d in", __FUNCTION__, __LINE__);
status_t err = 0;
bool ready = false;
mSidebandType = sidebandType;
mBuffMgr = common::TvInputBufferManager::GetInstance();
if (attr->struct_size != sizeof(vt_win_attr_t)) {
DEBUG_PRINT(3, "sideband info struct size is invailed!");
goto __FAILED;
}
memcpy(&mSidebandInfo, attr, sizeof(vt_win_attr_t));
ALOGD("RTSidebandWindow::init width=%d, height=%d, format=%x, usage=%lld, type=%d",
mSidebandInfo.width, mSidebandInfo.height, mSidebandInfo.format, (long long)mSidebandInfo.usage, sidebandType);
if (mSidebandType & TYPE_SIDEBAND_WINDOW) {
mVopRender = android::DrmVopRender::GetInstance();
if (!mVopRender->mInitialized) {
ready = mVopRender->initialize();
if (ready) {
mVopRender->detect();
}
}
} else if (mSidebandType & TYPE_SIDEBAND_VTUNNEL) {
mVTDevFd = rk_vt_open();
if (mVTDevFd < 0) {
ALOGE("rk_vt_open mVTDevFd=%d failed", mVTDevFd);
goto __FAILED;
}
err = rk_vt_alloc_id(mVTDevFd, &mVTID);
if (err < 0 || mVTID < 0) {
goto __ALLOC_ID_FAILED;
}
ALOGW("rk_vt_alloc_id vtunnel_id=%d", mVTID);
err = rk_vt_connect(mVTDevFd, mVTID, RKVT_ROLE_PRODUCER);
if (err < 0) {
ALOGE("rk_vt_connect vtunnel_id=%d failed", mVTID);
goto __CONNECT_FALED;
}
}
#if 0
mMessageThread = std::unique_ptr<MessageThread>(new MessageThread(this, "VOP Render"));
if (mMessageThread != NULL) {
mMessageThread->run();
}
#endif
return err;
__CONNECT_FALED:
rk_vt_free_id(mVTDevFd, mVTID);
__ALLOC_ID_FAILED:
rk_vt_close(mVTDevFd);
__FAILED:
return -1;
}
status_t RTSidebandWindow::release() {
ALOGW("%s mVTDevFd=%d, mVTID=%d", __FUNCTION__, mVTDevFd, mVTID);
if (mVTID >= 0) {
rk_vt_disconnect(mVTDevFd, mVTID, RKVT_ROLE_PRODUCER);
rk_vt_reset(mVTDevFd, mVTID);
rk_vt_free_id(mVTDevFd, mVTID);
rk_vt_close(mVTDevFd);
}
do {
android::Mutex::Autolock _l(mLock);
while (mBufferQueue.size() > 0) {
vt_buffer_t *tmpBuffer = mBufferQueue.front();
mBufferQueue.erase(mBufferQueue.begin());
freeBuffer(&tmpBuffer);
}
} while (0);
mRenderingCnt = 0;
return 0;
}
status_t RTSidebandWindow::stop() {
DEBUG_PRINT(3, "%s %d in", __FUNCTION__, __LINE__);
if (mVopRender) {
mVopRender->deinitialize();
//delete mVopRender;
//mVopRender = NULL;
}
return 0;
}
status_t RTSidebandWindow::flush() {
android::Mutex::Autolock _l(mLock);
while (mBufferQueue.size() > 0) {
vt_buffer_t *tmpBuffer = mBufferQueue.front();
mBufferQueue.erase(mBufferQueue.begin());
freeBuffer(&tmpBuffer);
}
mRenderingCnt = 0;
return rk_vt_reset(mVTDevFd, mVTID);
}
status_t RTSidebandWindow::setAttr(const vt_win_attr_t *attr) {
android::Mutex::Autolock _l(mLock);
if (attr->struct_size != sizeof(vt_win_attr_t)) {
ALOGE("setAttr: sideband window info struct size is invailed!");
return -1;
}
memcpy(&mSidebandInfo, attr, sizeof(vt_win_attr_t));
return 0;
}
status_t RTSidebandWindow::getAttr(vt_win_attr_t *info) {
android::Mutex::Autolock _l(mLock);
memcpy(info, &mSidebandInfo, sizeof(vt_win_attr_t));
return 0;
}
status_t RTSidebandWindow::allocateSidebandHandle(buffer_handle_t *handle,
int VTId) {
native_handle_t *temp_buffer = NULL;
vt_sideband_data_t info;
memset(&info, 0, sizeof(vt_sideband_data_t));
g_session_id++;
info.version = sizeof(vt_sideband_data_t);
info.tunnel_id = VTId > -1 ? VTId : mVTID;
info.crop.left = mSidebandInfo.left;
info.crop.top = mSidebandInfo.top;
info.crop.right = mSidebandInfo.right;
info.crop.bottom = mSidebandInfo.bottom;
info.width = mSidebandInfo.width;
info.height = mSidebandInfo.height;
info.format = mSidebandInfo.format;
info.transform = mSidebandInfo.transform;
info.usage = mSidebandInfo.usage;
info.data_space = mSidebandInfo.data_space;
info.compress_mode = mSidebandInfo.compress_mode;
info.session_id = g_session_id;
temp_buffer = native_handle_create(0, sizeof(vt_sideband_data_t) / sizeof(int));
temp_buffer->version = sizeof(native_handle_t);
temp_buffer->numFds = 0;
temp_buffer->numInts = sizeof(vt_sideband_data_t) / sizeof(int);
memcpy(&temp_buffer->data[0], &info, sizeof(vt_sideband_data_t));
*handle = (buffer_handle_t)temp_buffer;
ALOGI("allocate handle %p to native window session-id %lld",
temp_buffer, (long long)info.session_id);
ALOGI("allocate handle: tid[%d] crop[%d %d %d %d], wxh[%d %d] fmt[%d] " \
"transform[%d] usage[%p] data_space[%lld] compress_mode[%d]",
info.tunnel_id, info.crop.left, info.crop.top, info.crop.right,
info.crop.bottom, info.width, info.height, info.format, info.transform,
(void *)info.usage, (long long)info.data_space, info.compress_mode);
return 0;
}
status_t RTSidebandWindow::allocateBuffer(vt_buffer_t **buffer) {
return allocateBuffer(buffer,
mSidebandInfo.width, mSidebandInfo.height,
mSidebandInfo.format, mSidebandInfo.usage);
}
status_t RTSidebandWindow::allocateBuffer(vt_buffer_t **buffer,
int width, int32_t height, int32_t format, uint64_t usage) {
GraphicBufferAllocator &allocator = GraphicBufferAllocator::get();
buffer_handle_t temp_buffer = NULL;
uint32_t outStride = 0;
vt_buffer_t *vtBuffer = NULL;
status_t err = allocator.allocate(width, height,
format,
1,
usage,
&temp_buffer,
&outStride,
0,
std::move("videotunnel"));
if (err != NO_ERROR) {
return err;
}
vtBuffer = rk_vt_buffer_malloc();
vtBuffer->handle = (native_handle_t *)temp_buffer;
*buffer = vtBuffer;
ALOGI("allocate buffer: fd-0[%d] wxh[%d %d] fmt[0x%x] usage[%p]",
temp_buffer->data[0], width, height,
format, (void *)usage);
return 0;
}
status_t RTSidebandWindow::freeBuffer(vt_buffer_t **buffer) {
GraphicBufferAllocator &allocator = GraphicBufferAllocator::get();
ALOGI("free buffer: fd-0[%d] wxh[%d %d] fmt[0x%x] usage[%p]",
(*buffer)->handle->data[0], mSidebandInfo.width, mSidebandInfo.height,
mSidebandInfo.format, (void *)mSidebandInfo.usage);
allocator.free((*buffer)->handle);
(*buffer)->handle = NULL;
rk_vt_buffer_free(buffer);
*buffer = NULL;
return 0;
}
status_t RTSidebandWindow::dequeueBuffer(vt_buffer_t **buffer, int timeout_ms, int *fence) {
int err = 0;
vt_buffer_t *tmpBuffer = NULL;
{
android::Mutex::Autolock _l(mLock);
if (mBufferQueue.size() < mSidebandInfo.buffer_cnt) {
ALOGW("%s %d do allocateBuffer", __FUNCTION__, __LINE__);
err = allocateBuffer(buffer);
if (err == 0) {
mBufferQueue.push_back(*buffer);
}
return err;
}
}
err = rk_vt_dequeue_buffer(mVTDevFd, mVTID, timeout_ms, &tmpBuffer);
if (err != 0 && tmpBuffer == NULL) {
return err;
}
*buffer = tmpBuffer;
*fence = -1;
mRenderingCnt--;
return 0;
}
status_t RTSidebandWindow::queueBuffer(vt_buffer_t *buffer, int fence, int64_t expected_present_time) {
mRenderingCnt++;
buffer->crop.left = mSidebandInfo.left;
buffer->crop.top = mSidebandInfo.top;
buffer->crop.right = mSidebandInfo.right;
buffer->crop.bottom = mSidebandInfo.bottom;
return rk_vt_queue_buffer(mVTDevFd, mVTID, (vt_buffer_t *)buffer, expected_present_time);
}
status_t RTSidebandWindow::cancelBuffer(vt_buffer_t *buffer) {
{
android::Mutex::Autolock _l(mLock);
if (mRenderingCnt >= mSidebandInfo.remain_cnt) {
for (auto it = mBufferQueue.begin(); it != mBufferQueue.end(); it++) {
if (*it == buffer) {
mBufferQueue.erase(it);
return freeBuffer(&buffer);
}
}
if (buffer) {
if (buffer->handle) {
ALOGW("cancel buffer(%p) fd-0(%d) not allocate by sideband window.",
buffer, buffer->handle->data[0]);
} else {
ALOGE("%s cancel buffer(%p) but buffer->handle is NULL.",
__FUNCTION__, buffer);
}
} else {
ALOGE("%s cancel NULL buffer.", __FUNCTION__);
}
}
}
mRenderingCnt++;
return rk_vt_cancel_buffer(mVTDevFd, mVTID, buffer);
}
status_t RTSidebandWindow::flushCache(buffer_handle_t buffer) {
if (!buffer) {
DEBUG_PRINT(3, "%s param buffer is NULL.", __FUNCTION__);
return -1;
}
return mBuffMgr->FlushCache(buffer);
}
status_t RTSidebandWindow::allocateBuffer(buffer_handle_t *buffer) {
return allocateSidebandHandle(buffer,
mSidebandInfo.width,
mSidebandInfo.height,
mSidebandInfo.format,
mSidebandInfo.usage);
}
status_t RTSidebandWindow::allocateSidebandHandle(buffer_handle_t *handle,
int width, int32_t height, int32_t format, uint64_t usage) {
GraphicBufferAllocator &allocator = GraphicBufferAllocator::get();
buffer_handle_t temp_buffer = NULL;
uint32_t outStride = 0;
status_t err = allocator.allocate(-1 == width?mSidebandInfo.width:width,
-1 == height?mSidebandInfo.height:height,
-1 == format?mSidebandInfo.format:format,
1,
-1 == usage?0:usage,
&temp_buffer,
&outStride,
0,
std::move("tif_allocate"));
if (!temp_buffer) {
DEBUG_PRINT(3, "allocate failed !!!");
} else {
*handle = temp_buffer;
err = 0;
}
return err;
}
status_t RTSidebandWindow::freeBuffer(buffer_handle_t *buffer, int type) {
DEBUG_PRINT(3, "%s in type = %d", __FUNCTION__, type);
GraphicBufferAllocator &allocator = GraphicBufferAllocator::get();
allocator.free(*buffer);
return 0;
}
status_t RTSidebandWindow::setBufferGeometry(int32_t width, int32_t height, int32_t format) {
DEBUG_PRINT(mDebugLevel, "%s %d width=%d height=%d in", __FUNCTION__, __LINE__, width, height);
mSidebandInfo.width = width;
mSidebandInfo.height = height;
mSidebandInfo.format = format;
RTSidebandWindow::setAttr(&mSidebandInfo);
return 0;
}
status_t RTSidebandWindow::setCrop(int32_t left, int32_t top, int32_t right, int32_t bottom) {
mSidebandInfo.left = left;
mSidebandInfo.top = top;
mSidebandInfo.right = right;
mSidebandInfo.bottom = bottom;
RTSidebandWindow::setAttr(&mSidebandInfo);
return 0;
}
status_t RTSidebandWindow::requestExitAndWait()
{
Message msg;
memset(&msg, 0, sizeof(Message));
msg.id = MESSAGE_ID_EXIT;
status_t status = mMessageQueue.send(&msg, MESSAGE_ID_EXIT);
//status |= mMessageThread->requestExitAndWait();
return status;
}
void RTSidebandWindow::messageThreadLoop() {
mThreadRunning = true;
while (mThreadRunning) {
status_t status = NO_ERROR;
Message msg;
mMessageQueue.receive(&msg);
ALOGD("@%s, receive message id:%d", __FUNCTION__, msg.id);
switch (msg.id) {
case MESSAGE_ID_EXIT:
status = handleMessageExit();
break;
case MESSAGE_ID_RENDER_REQUEST:
status = handleRenderRequest(msg);
break;
case MESSAGE_ID_DEQUEUE_REQUEST:
status = handleDequeueRequest(msg);
break;
case MESSAGE_ID_FLUSH:
status = handleFlush();
break;
default:
DEBUG_PRINT(3, "ERROR Unknown message %d", msg.id);
status = BAD_VALUE;
break;
}
if (status != NO_ERROR)
DEBUG_PRINT(3, "error %d in handling message: %d", status, static_cast<int>(msg.id));
DEBUG_PRINT(mDebugLevel, "@%s, finish message id:%d", __FUNCTION__, msg.id);
mMessageQueue.reply(msg.id, status);
}
}
status_t RTSidebandWindow::handleMessageExit() {
mThreadRunning = false;
return 0;
}
status_t RTSidebandWindow::handleRenderRequest(Message &msg) {
buffer_handle_t buffer = msg.streamBuffer.buffer;
ALOGD("%s %d buffer: %p in", __FUNCTION__, __LINE__, buffer);
mVopRender->SetDrmPlane(0, mSidebandInfo.right - mSidebandInfo.left, mSidebandInfo.bottom - mSidebandInfo.top, buffer, FULL_SCREEN, HDMIIN_TYPE_HDMIRX);
mRenderingQueue.push_back(buffer);
ALOGD("%s mRenderingQueue.size() = %d", __FUNCTION__, (int32_t)mRenderingQueue.size());
return 0;
}
status_t RTSidebandWindow::show(buffer_handle_t handle, int displayRatio, int hdmiInType) {
if (mVopRender) {
mVopRender->SetDrmPlane(0, mSidebandInfo.right - mSidebandInfo.left, mSidebandInfo.bottom - mSidebandInfo.top,
handle, displayRatio, hdmiInType);
}
return 0;
}
void RTSidebandWindow::setDebugLevel(int debugLevel) {
if (mDebugLevel != debugLevel && mVopRender) {
mDebugLevel = debugLevel;
mVopRender->setDebugLevel(debugLevel);
}
}
status_t RTSidebandWindow::clearVopArea() {
ALOGD("RTSidebandWindow::clearVopArea()");
if (mVopRender) {
mVopRender->DestoryFB();
mVopRender->ClearDrmPlaneContent(0, mSidebandInfo.right - mSidebandInfo.left, mSidebandInfo.bottom - mSidebandInfo.top);
}
return 0;
}
status_t RTSidebandWindow::handleDequeueRequest(Message &msg) {
(void)msg;
mRenderingQueue.erase(mRenderingQueue.begin());
return 0;
}
status_t RTSidebandWindow::handleFlush() {
while (mRenderingQueue.size() > 0) {
buffer_handle_t buffer = NULL;
buffer = mRenderingQueue.front();
mRenderingQueue.erase(mRenderingQueue.begin());
freeBuffer(&buffer, 0);
}
return 0;
}
int RTSidebandWindow::getBufferHandleFd(buffer_handle_t buffer){
if (!buffer) {
DEBUG_PRINT(3, "%s param buffer is NULL.", __FUNCTION__);
return -1;
}
return mBuffMgr->GetHandleFd(buffer);
}
int RTSidebandWindow::getBufferLength(buffer_handle_t buffer) {
if (!buffer) {
DEBUG_PRINT(3, "%s param buffer is NULL.", __FUNCTION__);
return -1;
}
return mBuffMgr->GetHandleBufferSize(buffer);
}
int RTSidebandWindow::importHidlHandleBufferLocked(buffer_handle_t& rawHandle) {
ALOGD("%s rawBuffer :%p", __FUNCTION__, rawHandle);
if (rawHandle) {
if(!mBuffMgr->ImportBufferLocked(rawHandle)) {
return getBufferHandleFd(rawHandle);
} else {
ALOGE("%s failed.", __FUNCTION__);
}
}
return -1;
}
int RTSidebandWindow::buffDataTransfer(buffer_handle_t srcHandle, buffer_handle_t dstHandle) {
ALOGD("%s in srcHandle=%p, dstHandle=%p", __FUNCTION__, srcHandle, dstHandle);
std::string file1 = "/data/system/tv_input_src_dump.yuv";
std::string file2 = "/data/system/tv_input_result_dump.yuv";
if (srcHandle && dstHandle) {
void *tmpSrcPtr = NULL, *tmpDstPtr = NULL;
int srcDatasize = -1;
int lockMode = GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK | GRALLOC_USAGE_HW_CAMERA_MASK;
mBuffMgr->Lock(srcHandle, lockMode, 0, 0, mBuffMgr->GetWidth(srcHandle), mBuffMgr->GetHeight(srcHandle), &tmpSrcPtr);
for (int i = 0; i < mBuffMgr->GetNumPlanes(srcHandle); i++) {
srcDatasize += mBuffMgr->GetPlaneSize(srcHandle, i);
}
writeData2File(file1.c_str(), tmpSrcPtr, srcDatasize);
ALOGD("data tmpSrcPtr ptr = %p, srcDatasize=%d", tmpSrcPtr, srcDatasize);
mBuffMgr->LockLocked(dstHandle, lockMode, 0, 0, mBuffMgr->GetWidth(dstHandle), mBuffMgr->GetHeight(dstHandle), &tmpDstPtr);
ALOGD("data tmpDstPtr ptr = %p, width=%d, height=%d", tmpDstPtr, mBuffMgr->GetWidth(dstHandle), mBuffMgr->GetHeight(dstHandle));
std::memcpy(tmpDstPtr, tmpSrcPtr, srcDatasize);
writeData2File(file2.c_str(), tmpDstPtr, srcDatasize);
mBuffMgr->UnlockLocked(dstHandle);
mBuffMgr->Unlock(srcHandle);
ALOGD("%s end", __FUNCTION__);
return 0;
}
return -1;
}
int RTSidebandWindow::buffDataTransfer2(buffer_handle_t srcHandle, buffer_handle_t dstHandle) {
if (srcHandle && dstHandle) {
unsigned char* tmpSrcPtr = NULL;
unsigned char* tmpDstPtr = NULL;
int srcDatasize = -1;
int lockMode = GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK | GRALLOC_USAGE_HW_CAMERA_MASK;
mBuffMgr->Lock(srcHandle, lockMode, 0, 0, mBuffMgr->GetWidth(srcHandle), mBuffMgr->GetHeight(srcHandle), (void**)&tmpSrcPtr);
for (int i = 0; i < mBuffMgr->GetNumPlanes(srcHandle); i++) {
srcDatasize += mBuffMgr->GetPlaneSize(srcHandle, i);
}
mBuffMgr->LockLocked(dstHandle, lockMode, 0, 0, mBuffMgr->GetWidth(dstHandle), mBuffMgr->GetHeight(dstHandle), (void**)&tmpDstPtr);
int dstDatesize = -1;
for (int i = 0; i < mBuffMgr->GetNumPlanes(dstHandle); i++) {
dstDatesize += mBuffMgr->GetPlaneSize(dstHandle, i);
}
//ALOGD("%s %d %d", __FUNCTION__, srcDatasize, dstDatesize);
std::memcpy(tmpDstPtr, tmpSrcPtr, dstDatesize);
mBuffMgr->UnlockLocked(dstHandle);
mBuffMgr->Unlock(srcHandle);
return 0;
}
return -1;
}
int RTSidebandWindow::NV24ToNV12(buffer_handle_t srcHandle, buffer_handle_t dstHandle, int width, int height) {
if (srcHandle && dstHandle) {
//void *tmpSrcPtr = NULL, *tmpDstPtr = NULL;
unsigned char* tmpSrcPtr = NULL;
unsigned char* tmpDstPtr = NULL;
int srcDatasize = -1;
int lockMode = GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK | GRALLOC_USAGE_HW_CAMERA_MASK;
//DEBUG_PRINT(3, "%d %d", mBuffMgr->GetHandleBufferSize(srcHandle), mBuffMgr->GetHandleBufferSize(dstHandle));
mBuffMgr->Lock(srcHandle, lockMode, 0, 0, mBuffMgr->GetWidth(srcHandle), mBuffMgr->GetHeight(srcHandle), (void**)&tmpSrcPtr);
for (int i = 0; i < mBuffMgr->GetNumPlanes(srcHandle); i++) {
srcDatasize += mBuffMgr->GetPlaneSize(srcHandle, i);
}
//ALOGD("data tmpSrcPtr ptr = %p, srcDatasize=%d", tmpSrcPtr, srcDatasize);
mBuffMgr->LockLocked(dstHandle, lockMode, 0, 0, mBuffMgr->GetWidth(dstHandle), mBuffMgr->GetHeight(dstHandle), (void**)&tmpDstPtr);
//ALOGD("data tmpDstPtr ptr = %p, width=%d, height=%d", tmpDstPtr, mBuffMgr->GetWidth(dstHandle), mBuffMgr->GetHeight(dstHandle));
int i,j;
int width_uv_out = width / 2;
int height_uv_out = height / 2;
int uIn = width * height;
int uOut = width * height;
//ALOGD("==============start================%dX%d, %dX%d", width_uv_out, height_uv_out, width, height);
std::memcpy(tmpDstPtr, tmpSrcPtr, width*height);
for(i = 0; i < height_uv_out; i++) {
for(j = 0; j < width_uv_out; j++) {
int dstPos = uOut + i*width + j*2;
int srcPos = uIn + i*4*width + j*4;
std::memcpy(tmpDstPtr+dstPos, tmpSrcPtr+srcPos, 2);
}
}
mBuffMgr->UnlockLocked(dstHandle);
mBuffMgr->Unlock(srcHandle);
//ALOGD("==============end================");
return 0;
}
return -1;
}
void RTSidebandWindow::readDataFromFile(const char *file_path, buffer_handle_t dstHandle) {
FILE* fp = fopen(file_path, "rb");
if(fp == NULL) {
ALOGD("open file %s , error %s\n", file_path, strerror(errno));
return;
}
unsigned int filesize = -1;
struct stat statbuff;
if (stat(file_path, &statbuff) < 0) {
return;
}
filesize = statbuff.st_size;
ALOGD("%s(%d) size of file :%s size is :\t%u bytes\n",
__func__, __LINE__, file_path, filesize);
unsigned char* tmpDstPtr = NULL;
int lockMode = GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK | GRALLOC_USAGE_HW_CAMERA_MASK;
mBuffMgr->LockLocked(dstHandle, lockMode, 0, 0, mBuffMgr->GetWidth(dstHandle), mBuffMgr->GetHeight(dstHandle), (void**)&tmpDstPtr);
unsigned int num_read = fread(tmpDstPtr, filesize, 1,fp);
ALOGD("fread num is %u\n", num_read);
fclose(fp);
mBuffMgr->UnlockLocked(dstHandle);
}
int RTSidebandWindow::writeData2File(const char *fileName, void *data, int dataSize) {
int ret = 0;
FILE* fp = NULL;
fp = fopen(fileName, "wb+");
if (fp != NULL) {
if (fwrite(data, dataSize, 1, fp) <= 0) {
ALOGE("fwrite %s failed.", fileName);
ret = -1;
} else {
ALOGD("fwirte %s success", fileName);
}
} else {
ALOGE("open failed");
ret = -1;
}
fclose(fp);
return ret;
}
int RTSidebandWindow::dumpImage(buffer_handle_t handle, char* fileName, int mode) {
int ret = -1;
if (!handle || !fileName) {
DEBUG_PRINT(3, "%s param buffer is NULL.", __FUNCTION__);
return ret;
}
ALOGD("%s handle :%p", __FUNCTION__, handle);
FILE* fp = NULL;
void *dataPtr = NULL;
int dataSize = 0;
fp = fopen(fileName, "wb+");
if (fp != NULL) {
struct android_ycbcr ycbrData;
int lockMode = GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK | GRALLOC_USAGE_HW_CAMERA_MASK;
if (mode == 1) {
mBuffMgr->LockYCbCr(handle, lockMode, 0, 0, mBuffMgr->GetWidth(handle), mBuffMgr->GetHeight(handle), &ycbrData);
dataPtr = ycbrData.y;
} else {
ALOGD("width = %d", mBuffMgr->GetWidth(handle));
ALOGD("height = %d", mBuffMgr->GetHeight(handle));
mBuffMgr->LockLocked(handle, lockMode, 0, 0, mBuffMgr->GetWidth(handle), mBuffMgr->GetHeight(handle), &dataPtr);
}
ALOGD("planesNum = %d", mBuffMgr->GetNumPlanes(handle));
for (int i = 0; i < mBuffMgr->GetNumPlanes(handle); i++) {
ALOGD("planesSize = %zu", mBuffMgr->GetPlaneSize(handle, i));
dataSize += mBuffMgr->GetPlaneSize(handle, i);
}
if (dataSize <= 0) {
ALOGE("dataSize <= 0 , it can't write file.");
ret = -1;
} else {
if (fwrite(dataPtr, dataSize, 1, fp) <= 0) {
ALOGE("fwrite %s failed.", fileName);
ret = -1;
}
}
fclose(fp);
if (mode == 0) {
mBuffMgr->UnlockLocked(handle);
} else {
mBuffMgr->Unlock(handle);
}
ALOGI("Write data success to %s",fileName);
ret = 0;
} else {
DEBUG_PRINT(3, "Create %s failed(%p, %s)", fileName, fp, strerror(errno));
}
return ret;
}
int RTSidebandWindow::getSidebandPlaneId() {
if (mVopRender) {
return mVopRender->getSidebandPlaneId();
} else {
return 0;
}
}
}