/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #define LOG_TAG "DualFOVPP" // System dependencies #include #include #include #include // Camera dependencies #include "QCameraDualFOVPP.h" #include "QCameraTrace.h" #include "cam_intf.h" extern "C" { #include "mm_camera_dbg.h" } #define LIB_PATH_LENGTH 100 namespace qcamera { /*=========================================================================== * FUNCTION : QCameraDualFOVPP * * DESCRIPTION: constructor of QCameraDualFOVPP. * * PARAMETERS : None * * RETURN : None *==========================================================================*/ QCameraDualFOVPP::QCameraDualFOVPP() : QCameraHALPP() { m_dlHandle = NULL; m_pCaps = NULL; } /*=========================================================================== * FUNCTION : ~QCameraDualFOVPP * * DESCRIPTION: destructor of QCameraDualFOVPP. * * PARAMETERS : None * * RETURN : None *==========================================================================*/ QCameraDualFOVPP::~QCameraDualFOVPP() { } /*=========================================================================== * FUNCTION : init * * DESCRIPTION: initialization of QCameraDualFOVPP * * PARAMETERS : * @bufNotifyCb : call back function after HALPP process * @getOutputCb : call back function to request output buffe * @pUserData : Parent of HALPP, i.e. QCameraPostProc * @pStaticParam : holds dual camera calibration data in an array and its size * (expected size is 264 bytes) * * RETURN : int32_t type of status * NO_ERROR -- success * none-zero failure code *==========================================================================*/ int32_t QCameraDualFOVPP::init(halPPBufNotify bufNotifyCb, halPPGetOutput getOutputCb, void *pUserData, void *pStaticParam) { LOGD("E"); int32_t rc = NO_ERROR; QCameraHALPP::init(bufNotifyCb, getOutputCb, pUserData); m_pCaps = (cam_capability_t *)pStaticParam; /* we should load 3rd libs here, with dlopen/dlsym */ doDualFovPPInit(); LOGD("X"); return rc; } /*=========================================================================== * FUNCTION : deinit * * DESCRIPTION: de initialization of QCameraDualFOVPP * * PARAMETERS : None * * RETURN : int32_t type of status * NO_ERROR -- success * none-zero failure code *==========================================================================*/ int32_t QCameraDualFOVPP::deinit() { int32_t rc = NO_ERROR; LOGD("E"); m_dlHandle = NULL; QCameraHALPP::deinit(); LOGD("X"); return rc; } /*=========================================================================== * FUNCTION : start * * DESCRIPTION: starting QCameraDualFOVPP * * PARAMETERS : * * RETURN : int32_t type of status * NO_ERROR -- success * none-zero failure code *==========================================================================*/ int32_t QCameraDualFOVPP::start() { int32_t rc = NO_ERROR; LOGD("E"); rc = QCameraHALPP::start(); LOGD("X"); return rc; } /*=========================================================================== * FUNCTION : feedInput * * DESCRIPTION: function to feed input data. * Enqueue the frame index to inputQ if it is new frame * Also, add the input image data to frame hash map * * PARAMETERS : * @pInput : ptr to input data * * RETURN : int32_t type of status * NO_ERROR -- success * none-zero failure code *==========================================================================*/ int32_t QCameraDualFOVPP::feedInput(qcamera_hal_pp_data_t *pInputData) { int32_t rc = NO_ERROR; LOGD("E"); if (NULL != pInputData) { QCameraStream* pSnapshotStream = NULL; mm_camera_buf_def_t *pInputSnapshotBuf = getSnapshotBuf(pInputData, pSnapshotStream); if (pInputSnapshotBuf != NULL) { uint32_t frameIndex = pInputSnapshotBuf->frame_idx; std::vector *pVector = getFrameVector(frameIndex); if(pVector == NULL) { LOGD("insert new frame index = %d", frameIndex); uint32_t *pFrameIndex = new uint32_t; *pFrameIndex = frameIndex; // new the vector first pVector = new std::vector(WIDE_TELE_CAMERA_NUMBER); pVector->at(WIDE_INPUT) = NULL; pVector->at(TELE_INPUT) = NULL; // Add vector to the hash map m_frameMap[frameIndex] = pVector; // Enqueue the frame index (i.e. key of vector) to queue if (false == m_iuputQ.enqueue((void*)pFrameIndex)) { LOGE("Input Q is not active!!!"); releaseData(pInputData); m_frameMap.erase(frameIndex); delete pFrameIndex; delete pVector; rc = INVALID_OPERATION; return rc; } } pInputData->frameIndex = frameIndex; // Check if frame is from main wide camera bool bIsMain = true; uint32_t mainHandle = get_main_camera_handle( pInputData->src_reproc_frame->camera_handle); if (mainHandle == 0) { bIsMain = false; } LOGD("mainHandle = %d, is main frame = %d", mainHandle, bIsMain); // Add input data to vector if (bIsMain) { pVector->at(WIDE_INPUT) = pInputData; } else { pVector->at(TELE_INPUT) = pInputData; } // request output buffer only if both wide and tele input data are recieved if (pVector->at(0) != NULL && pVector->at(1) != NULL) { m_halPPGetOutputCB(frameIndex, m_pQCameraPostProc); } } } else { LOGE("pInput is NULL"); rc = UNEXPECTED_NULL; } LOGD("X"); return rc; } /*=========================================================================== * FUNCTION : feedOutput * * DESCRIPTION: function to feed output buffer and metadata * * PARAMETERS : * @pOutput : ptr to output data * * RETURN : int32_t type of status * NO_ERROR -- success * none-zero failure code *==========================================================================*/ int32_t QCameraDualFOVPP::feedOutput(qcamera_hal_pp_data_t *pOutputData) { int32_t rc = NO_ERROR; LOGD("E"); if (NULL != pOutputData) { uint32_t frameIndex = pOutputData->frameIndex; std::vector *pVector = getFrameVector(frameIndex); // Get the main (Wide) input frame in order to get output buffer len, // and copy metadata buffer. if (pVector != NULL && pVector->at(WIDE_INPUT) != NULL) { qcamera_hal_pp_data_t *pInputData = pVector->at(WIDE_INPUT); mm_camera_super_buf_t *pInputFrame = pInputData->frame; QCameraStream* pSnapshotStream = NULL; QCameraStream* pMetadataStream = NULL; mm_camera_buf_def_t *pInputSnapshotBuf = getSnapshotBuf(pInputData, pSnapshotStream); mm_camera_buf_def_t *pInputMetadataBuf = getMetadataBuf(pInputData, pMetadataStream); mm_camera_super_buf_t *pOutputFrame = pOutputData->frame; mm_camera_buf_def_t *pOutputBufDefs = pOutputData->bufs; if (pInputSnapshotBuf == NULL || pInputMetadataBuf == NULL) { LOGE("cannot get sanpshot or metadata buf def"); releaseData(pOutputData); return UNEXPECTED_NULL; } if (pSnapshotStream == NULL || pMetadataStream == NULL) { LOGE("cannot get sanpshot or metadata stream"); releaseData(pOutputData); return UNEXPECTED_NULL; } // Copy main input frame info to output frame pOutputFrame->camera_handle = pInputFrame->camera_handle; pOutputFrame->ch_id = pInputFrame->ch_id; pOutputFrame->num_bufs = HAL_PP_NUM_BUFS;//snapshot and metadata pOutputFrame->bUnlockAEC = pInputFrame->bUnlockAEC; pOutputFrame->bReadyForPrepareSnapshot = pInputFrame->bReadyForPrepareSnapshot; // Reconstruction of output_frame super buffer pOutputFrame->bufs[0] = &pOutputBufDefs[0]; pOutputFrame->bufs[1] = &pOutputBufDefs[1]; // Allocate heap buffer for output image frame cam_frame_len_offset_t offset; memset(&offset, 0, sizeof(cam_frame_len_offset_t)); LOGD("pInputSnapshotBuf->frame_len = %d", pInputSnapshotBuf->frame_len); rc = pOutputData->snapshot_heap->allocate(1, pInputSnapshotBuf->frame_len); if (rc < 0) { LOGE("Unable to allocate heap memory for image buf"); releaseData(pOutputData); return NO_MEMORY; } pSnapshotStream->getFrameOffset(offset); memcpy(&pOutputBufDefs[0], pInputSnapshotBuf, sizeof(mm_camera_buf_def_t)); LOGD("pOutputFrame->bufs[0]->fd = %d, pOutputFrame->bufs[0]->buffer = %x", pOutputFrame->bufs[0]->fd, pOutputFrame->bufs[0]->buffer); pOutputData->snapshot_heap->getBufDef(offset, pOutputBufDefs[0], 0); LOGD("pOutputFrame->bufs[0]->fd = %d, pOutputFrame->bufs[0]->buffer = %x", pOutputFrame->bufs[0]->fd, pOutputFrame->bufs[0]->buffer); // Allocate heap buffer for output metadata LOGD("pInputMetadataBuf->frame_len = %d", pInputMetadataBuf->frame_len); rc = pOutputData->metadata_heap->allocate(1, pInputMetadataBuf->frame_len); if (rc < 0) { LOGE("Unable to allocate heap memory for metadata buf"); releaseData(pOutputData); return NO_MEMORY; } memset(&offset, 0, sizeof(cam_frame_len_offset_t)); pMetadataStream->getFrameOffset(offset); memcpy(&pOutputBufDefs[1], pInputMetadataBuf, sizeof(mm_camera_buf_def_t)); pOutputData->metadata_heap->getBufDef(offset, pOutputBufDefs[1], 0); // copy the whole metadata memcpy(pOutputBufDefs[1].buffer, pInputMetadataBuf->buffer, pInputMetadataBuf->frame_len); // Enqueue output_data to m_outgoingQ if (false == m_outgoingQ.enqueue((void *)pOutputData)) { LOGE("outgoing Q is not active!!!"); releaseData(pOutputData); rc = INVALID_OPERATION; } } } else { LOGE("pOutput is NULL"); rc = UNEXPECTED_NULL; } LOGD("X"); return rc; } /*=========================================================================== * FUNCTION : process * * DESCRIPTION: function to start CP FOV blending process * * PARAMETERS : None * * RETURN : int32_t type of status * NO_ERROR -- success * none-zero failure code *==========================================================================*/ int32_t QCameraDualFOVPP::process() { int32_t rc = NO_ERROR; /* dump in/out frames */ char prop[PROPERTY_VALUE_MAX]; memset(prop, 0, sizeof(prop)); property_get("persist.camera.dualfov.dumpimg", prop, "0"); int dumpimg = atoi(prop); LOGD("E"); // TODO: dequeue from m_inputQ and start process logic // Start the blending process when it is ready if (canProcess()) { LOGI("start Dual FOV process"); uint32_t *pFrameIndex = (uint32_t *)m_iuputQ.dequeue(); if (pFrameIndex == NULL) { LOGE("frame index is null"); return UNEXPECTED_NULL; } uint32_t frameIndex = *pFrameIndex; std::vector *pVector = getFrameVector(frameIndex); // Search vector of input frames in frame map if (pVector == NULL) { LOGE("Cannot find vecotr of input frames"); return UNEXPECTED_NULL; } // Get input and output frame buffer qcamera_hal_pp_data_t *pInputMainData = (qcamera_hal_pp_data_t *)pVector->at(WIDE_INPUT); if (pInputMainData == NULL) { LOGE("Cannot find input main data"); return UNEXPECTED_NULL; } if (pInputMainData->src_reproc_frame == NULL) { LOGI("process pInputMainData->src_reproc_frame = NULL"); } //mm_camera_super_buf_t *input_main_frame = input_main_data->frame; qcamera_hal_pp_data_t *pInputAuxData = (qcamera_hal_pp_data_t *)pVector->at(TELE_INPUT); if (pInputAuxData == NULL) { LOGE("Cannot find input aux data"); return UNEXPECTED_NULL; } //mm_camera_super_buf_t *input_aux_frame = input_aux_data->frame; qcamera_hal_pp_data_t *pOutputData = (qcamera_hal_pp_data_t*)m_outgoingQ.dequeue(); if (pOutputData == NULL) { LOGE("Cannot find output data"); return UNEXPECTED_NULL; } QCameraStream* pMainSnapshotStream = NULL; QCameraStream* pMainMetadataStream = NULL; QCameraStream* pAuxSnapshotStream = NULL; QCameraStream* pAuxMetadataStream = NULL; mm_camera_buf_def_t *main_snapshot_buf = getSnapshotBuf(pInputMainData, pMainSnapshotStream); if (main_snapshot_buf == NULL) { LOGE("main_snapshot_buf is NULL"); return UNEXPECTED_NULL; } mm_camera_buf_def_t *main_meta_buf = getMetadataBuf(pInputMainData, pMainMetadataStream); if (main_meta_buf == NULL) { LOGE("main_meta_buf is NULL"); return UNEXPECTED_NULL; } mm_camera_buf_def_t *aux_snapshot_buf = getSnapshotBuf(pInputAuxData, pAuxSnapshotStream); if (aux_snapshot_buf == NULL) { LOGE("aux_snapshot_buf is NULL"); return UNEXPECTED_NULL; } mm_camera_buf_def_t *aux_meta_buf = getMetadataBuf(pInputAuxData, pAuxMetadataStream); if (aux_meta_buf == NULL) { LOGE("aux_meta_buf is NULL"); return UNEXPECTED_NULL; } mm_camera_super_buf_t *output_frame = pOutputData->frame; mm_camera_buf_def_t *output_snapshot_buf = output_frame->bufs[0]; // Use offset info from reproc stream if (pMainSnapshotStream == NULL) { LOGE("pMainSnapshotStream is NULL"); return UNEXPECTED_NULL; } cam_frame_len_offset_t frm_offset; pMainSnapshotStream->getFrameOffset(frm_offset); LOGI("Stream type:%d, stride:%d, scanline:%d, frame len:%d", pMainSnapshotStream->getMyType(), frm_offset.mp[0].stride, frm_offset.mp[0].scanline, frm_offset.frame_len); if (dumpimg) { dumpYUVtoFile((uint8_t *)main_snapshot_buf->buffer, frm_offset, main_snapshot_buf->frame_idx, "wide"); dumpYUVtoFile((uint8_t *)aux_snapshot_buf->buffer, frm_offset, aux_snapshot_buf->frame_idx, "tele"); } //Get input and output parameter dualfov_input_params_t inParams; if (pAuxSnapshotStream == NULL) { LOGE("pAuxSnapshotStream is NULL"); return UNEXPECTED_NULL; } getInputParams(main_meta_buf, aux_meta_buf, pMainSnapshotStream, pAuxSnapshotStream, inParams); dumpInputParams(inParams); doDualFovPPProcess((const uint8_t *)main_snapshot_buf->buffer, (const uint8_t *)aux_snapshot_buf->buffer, inParams, (uint8_t *)output_snapshot_buf->buffer); if (dumpimg) { dumpYUVtoFile((uint8_t *)output_snapshot_buf->buffer, frm_offset, main_snapshot_buf->frame_idx, "out"); } /* clean and invalidate caches, for input and output buffers*/ pOutputData->snapshot_heap->cleanInvalidateCache(0); QCameraMemory *pMem = (QCameraMemory *)main_snapshot_buf->mem_info; pMem->invalidateCache(main_snapshot_buf->buf_idx); pMem = (QCameraMemory *)aux_snapshot_buf->mem_info; pMem->invalidateCache(aux_snapshot_buf->buf_idx); // Calling cb function to return output_data after processed. m_halPPBufNotifyCB(pOutputData, m_pQCameraPostProc); // also send input buffer to postproc. m_halPPBufNotifyCB(pInputMainData, m_pQCameraPostProc); m_halPPBufNotifyCB(pInputAuxData, m_pQCameraPostProc); //releaseData(pInputMainData); //releaseData(pInputAuxData); // Release internal resource m_frameMap.erase(frameIndex); delete pFrameIndex; delete pVector; } LOGD("X"); return rc; } /*=========================================================================== * FUNCTION : getSnapshotBuf * * DESCRIPTION: function to get snapshot buf def and the stream from frame * PARAMETERS : * @pData : input frame super buffer * @pSnapshotStream : stream of snapshot that found * RETURN : snapshot buf def *==========================================================================*/ mm_camera_buf_def_t* QCameraDualFOVPP::getSnapshotBuf(qcamera_hal_pp_data_t* pData, QCameraStream* &pSnapshotStream) { mm_camera_buf_def_t *pBufDef = NULL; if (pData == NULL) { LOGE("Cannot find input frame super buffer"); return pBufDef; } mm_camera_super_buf_t *pFrame = pData->frame; QCameraChannel *pChannel = m_pQCameraPostProc->getChannelByHandle(pFrame->ch_id); if (pChannel == NULL) { LOGE("Cannot find channel"); return pBufDef; } // Search for input snapshot frame buf for (uint32_t i = 0; i < pFrame->num_bufs; i++) { pSnapshotStream = pChannel->getStreamByHandle(pFrame->bufs[i]->stream_id); if (pSnapshotStream != NULL) { if (pSnapshotStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT) || pSnapshotStream->isOrignalTypeOf(CAM_STREAM_TYPE_SNAPSHOT)) { pBufDef = pFrame->bufs[i]; break; } } } return pBufDef; } /*=========================================================================== * FUNCTION : getMetadataBuf * * DESCRIPTION: function to get metadata buf def and the stream from frame * PARAMETERS : * @pData : input frame super buffer * @pMetadataStream : stream of metadata that found * RETURN : metadata buf def *==========================================================================*/ mm_camera_buf_def_t* QCameraDualFOVPP::getMetadataBuf(qcamera_hal_pp_data_t *pData, QCameraStream* &pMetadataStream) { mm_camera_buf_def_t *pBufDef = NULL; if (pData == NULL) { LOGE("Cannot find input frame super buffer"); return pBufDef; } mm_camera_super_buf_t* pFrame = pData->frame; QCameraChannel *pChannel = m_pQCameraPostProc->getChannelByHandle(pData->src_reproc_frame->ch_id); LOGD("src_reproc_frame num_bufs = %d", pFrame->num_bufs); if (pChannel == NULL) { LOGE("Cannot find src_reproc_frame channel"); return pBufDef; } for (uint32_t i = 0; (i < pData->src_reproc_frame->num_bufs); i++) { pMetadataStream = pChannel->getStreamByHandle(pData->src_reproc_frame->bufs[i]->stream_id); if (pData->src_reproc_frame->bufs[i]->stream_type == CAM_STREAM_TYPE_METADATA) { pBufDef = pData->src_reproc_frame->bufs[i]; LOGD("find metadata stream and buf from src_reproc_frame"); break; } } if (pBufDef == NULL) { LOGD("frame num_bufs = %d", pFrame->num_bufs); pChannel = m_pQCameraPostProc->getChannelByHandle(pFrame->ch_id); if (pChannel == NULL) { LOGE("Cannot find frame channel"); return pBufDef; } for (uint32_t i = 0; i < pFrame->num_bufs; i++) { pMetadataStream = pChannel->getStreamByHandle(pFrame->bufs[i]->stream_id); if (pMetadataStream != NULL) { LOGD("bufs[%d] stream_type = %d", i, pFrame->bufs[i]->stream_type); if (pFrame->bufs[i]->stream_type == CAM_STREAM_TYPE_METADATA) { pBufDef = pFrame->bufs[i]; break; } } } } return pBufDef; } /*=========================================================================== * FUNCTION : canProcess * * DESCRIPTION: function to release internal resources * RETURN : If CP FOV can start blending process *==========================================================================*/ bool QCameraDualFOVPP::canProcess() { LOGD("E"); bool ready = false; if(!m_iuputQ.isEmpty() && !m_outgoingQ.isEmpty()) { ready = true; } LOGD("X"); return ready; } /*=========================================================================== * FUNCTION : getInputParams * * DESCRIPTION: Helper function to get input params from input metadata *==========================================================================*/ void QCameraDualFOVPP::getInputParams(mm_camera_buf_def_t *pMainMetaBuf, mm_camera_buf_def_t *pAuxMetaBuf, QCameraStream* pMainSnapshotStream, QCameraStream* pAuxSnapshotStream, dualfov_input_params_t& inParams) { LOGD("E"); memset(&inParams, 0, sizeof(dualfov_input_params_t)); metadata_buffer_t *pMainMeta = (metadata_buffer_t *)pMainMetaBuf->buffer; metadata_buffer_t *pAuxMeta = (metadata_buffer_t *)pAuxMetaBuf->buffer; // Wide frame size cam_frame_len_offset_t offset; pMainSnapshotStream->getFrameOffset(offset); inParams.wide.width = offset.mp[0].width; inParams.wide.height = offset.mp[0].height; inParams.wide.stride = offset.mp[0].stride; inParams.wide.scanline = offset.mp[0].scanline; inParams.wide.frame_len = offset.frame_len; // Tele frame size pAuxSnapshotStream->getFrameOffset(offset); inParams.tele.width = offset.mp[0].width; inParams.tele.height = offset.mp[0].height; inParams.tele.stride = offset.mp[0].stride; inParams.tele.scanline = offset.mp[0].scanline; inParams.tele.frame_len = offset.frame_len; // user_zoom int32_t zoom_level = -1; // 0 means zoom 1x. IF_META_AVAILABLE(int32_t, userZoom, CAM_INTF_PARM_ZOOM, pMainMeta) { zoom_level = *userZoom; LOGD("zoom level in main meta:%d", zoom_level); } inParams.user_zoom= getUserZoomRatio(zoom_level); LOGI("dual fov total zoom ratio: %d", inParams.user_zoom); IF_META_AVAILABLE(int32_t, auxUserZoom, CAM_INTF_PARM_ZOOM, pAuxMeta) { LOGD("zoom level in aux meta:%d", *auxUserZoom); } IF_META_AVAILABLE(uint32_t, afState, CAM_INTF_META_AF_STATE, pMainMeta) { if (((*afState) == CAM_AF_STATE_FOCUSED_LOCKED) || ((*afState) == CAM_AF_STATE_PASSIVE_FOCUSED)) { inParams.af_status = AF_STATUS_VALID; } else { inParams.af_status = AF_STATUS_INVALID; } LOGD("af state:%d, output af status:%d", *afState, inParams.af_status); } IF_META_AVAILABLE(uint32_t, auxAfState, CAM_INTF_META_AF_STATE, pAuxMeta) { int aux_af_status = 0; if (((*auxAfState) == CAM_AF_STATE_FOCUSED_LOCKED) || ((*auxAfState) == CAM_AF_STATE_PASSIVE_FOCUSED)) { aux_af_status = AF_STATUS_VALID; } else { aux_af_status = AF_STATUS_INVALID; } LOGD("aux af state:%d, output af status:%d", *auxAfState, aux_af_status); } LOGD("X"); } int32_t QCameraDualFOVPP::doDualFovPPInit() { LOGD("E"); int rc = NO_ERROR; LOGD("X"); return rc; } int32_t QCameraDualFOVPP::doDualFovPPProcess(const uint8_t* pWide, const uint8_t* pTele, dualfov_input_params_t inParams, uint8_t* pOut) { LOGW("E."); // trace begin // half image from main, and half image from tele // Y memcpy(pOut, pWide, inParams.wide.stride * inParams.wide.scanline / 2); memcpy(pOut + inParams.wide.stride * inParams.wide.scanline / 2, pTele + inParams.wide.stride * inParams.wide.scanline / 2, inParams.wide.stride * inParams.wide.scanline / 2); // UV uint32_t uv_offset = inParams.wide.stride * inParams.wide.scanline; memcpy(pOut + uv_offset, pWide + uv_offset, inParams.wide.stride * (inParams.wide.scanline / 2) / 2); memcpy(pOut + uv_offset + inParams.wide.stride * (inParams.wide.scanline / 2) / 2, pTele + uv_offset + inParams.wide.stride * (inParams.wide.scanline / 2) / 2, inParams.wide.stride * (inParams.wide.scanline / 2) / 2); // trace end LOGW("X."); return NO_ERROR; } uint32_t QCameraDualFOVPP::getUserZoomRatio(int32_t zoom_level) { uint32_t zoom_ratio = 4096; LOGD("E. input zoom level:%d", zoom_level); if (zoom_level < 0) { LOGW("invalid zoom evel!"); /* got the zoom value from QCamera2HWI Parameters */ zoom_level = 0; } // user_zoom_ratio = qcom_zoom_ratio * 4096 / 100 if (m_pCaps != NULL) { zoom_ratio *= m_pCaps->zoom_ratio_tbl[zoom_level]; zoom_ratio /= 100; LOGD("converted zoom ratio:%d", zoom_ratio); } LOGD("X. zoom_ratio:%d", zoom_ratio); return zoom_ratio; } void QCameraDualFOVPP::dumpYUVtoFile(const uint8_t* pBuf, cam_frame_len_offset_t offset, uint32_t idx, const char* name_prefix) { LOGD("E."); char filename[256]; snprintf(filename, sizeof(filename), QCAMERA_DUMP_FRM_LOCATION"%s_%dx%d_%d.yuv", name_prefix, offset.mp[0].stride, offset.mp[0].scanline, idx); QCameraHALPP::dumpYUVtoFile(pBuf,(const char*)filename, offset.frame_len); LOGD("X."); } void QCameraDualFOVPP::dumpInputParams(const dualfov_input_params_t& p) { LOGD("E"); const cam_frame_size_t* s = NULL; s = &p.wide; LOGD("wide frame size: %d, %d, stride:%d, scanline:%d", s->width, s->height, s->stride, s->scanline); s = &p.tele; LOGD("wide frame size: %d, %d, stride:%d, scanline:%d", s->width, s->height, s->stride, s->scanline); LOGD("zoom ratio: %f", p.user_zoom / 4096.0); LOGD("X"); } /*=========================================================================== * FUNCTION : dumpOISData * * DESCRIPTION: Read Sensor OIS data from metadata and dump it * * PARAMETERS : * @pMetadata : Frame metadata * * RETURN : None * *==========================================================================*/ void QCameraDualFOVPP::dumpOISData(metadata_buffer_t* pMetadata) { if (!pMetadata) { LOGD("OIS data not available"); return; } IF_META_AVAILABLE(cam_ois_data_t, pOisData, CAM_INTF_META_OIS_READ_DATA, pMetadata) { LOGD("Ois Data: data size: %d", pOisData->size); uint8_t *data = pOisData->data; if (pOisData->size == 8) { LOGD("Ois Data Buffer : %d %d %d %d %d %d %d %d ", data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]); } } return; } } // namespace qcamera