From 3dd1d4cba8e8e6fc9a064c6136abd491c0485446 Mon Sep 17 00:00:00 2001 From: Guruprasad Gaonkar Date: Tue, 5 Apr 2016 19:03:59 -0700 Subject: [PATCH] QCamera2:HAL1: Update native handle for every timestamp callback Incase framework updates camera native_handle pointer, we need to use cached native_handle to update for every timestamp callback. This change is excecuted only if media extension flag is enabled for the target. Issue: Use case introduced in video to overwrites camera native handle pointer. Fix: Change is to cache camera native handle and restore when video release camera buffer. Change-Id: I0bdc01b3f2b51d7bba66320cc8ef1ab019136d4e --- camera/QCamera2/Android.mk | 6 +- camera/QCamera2/HAL/QCamera2HWI.cpp | 7 +- camera/QCamera2/HAL/QCamera2HWICallbacks.cpp | 24 +-- camera/QCamera2/HAL/QCameraMem.cpp | 151 +++++++++++++++---- camera/QCamera2/HAL/QCameraMem.h | 3 + 5 files changed, 141 insertions(+), 50 deletions(-) mode change 100644 => 100755 camera/QCamera2/HAL/QCameraMem.cpp diff --git a/camera/QCamera2/Android.mk b/camera/QCamera2/Android.mk index f8a448a..b804f6a 100644 --- a/camera/QCamera2/Android.mk +++ b/camera/QCamera2/Android.mk @@ -50,6 +50,11 @@ ifeq ($(TARGET_USES_AOSP),true) LOCAL_CFLAGS += -DVANILLA_HAL endif +#use media extension +ifeq ($(TARGET_USES_MEDIA_EXTENSIONS), true) +LOCAL_CFLAGS += -DUSE_MEDIA_EXTENSIONS +endif + #HAL 1.0 Flags LOCAL_CFLAGS += -DDEFAULT_DENOISE_MODE_ON -DHAL3 -DQCAMERA_REDEFINE_LOG @@ -109,5 +114,4 @@ LOCAL_32_BIT_ONLY := $(BOARD_QTI_CAMERA_32BIT_ONLY) include $(BUILD_SHARED_LIBRARY) include $(call first-makefiles-under,$(LOCAL_PATH)) - endif diff --git a/camera/QCamera2/HAL/QCamera2HWI.cpp b/camera/QCamera2/HAL/QCamera2HWI.cpp index 304859f..0d084e3 100644 --- a/camera/QCamera2/HAL/QCamera2HWI.cpp +++ b/camera/QCamera2/HAL/QCamera2HWI.cpp @@ -775,6 +775,10 @@ void QCamera2HardwareInterface::release_recording_frame( return; } LOGD("E camera id %d", hw->getCameraId()); + + //Close and delete duplicated native handle and FD's. + QCameraVideoMemory::closeNativeHandle(opaque, hw->mStoreMetaDataInFrame > 0); + hw->lockAPI(); qcamera_api_result_t apiResult; int32_t ret = hw->processAPI(QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME, (void *)opaque); @@ -3685,8 +3689,9 @@ int QCamera2HardwareInterface::releaseRecordingFrame(const void * opaque) { int32_t rc = UNKNOWN_ERROR; QCameraVideoChannel *pChannel = - (QCameraVideoChannel *)m_channels[QCAMERA_CH_TYPE_VIDEO]; + (QCameraVideoChannel *)m_channels[QCAMERA_CH_TYPE_VIDEO]; LOGD("opaque data = %p",opaque); + if(pChannel != NULL) { rc = pChannel->releaseFrame(opaque, mStoreMetaDataInFrame > 0); } diff --git a/camera/QCamera2/HAL/QCamera2HWICallbacks.cpp b/camera/QCamera2/HAL/QCamera2HWICallbacks.cpp index a8722f1..8e08c9f 100644 --- a/camera/QCamera2/HAL/QCamera2HWICallbacks.cpp +++ b/camera/QCamera2/HAL/QCamera2HWICallbacks.cpp @@ -37,9 +37,6 @@ #include STAT_H #include -// OpenMAX dependencies -#include "QComOMXMetadata.h" - // Camera dependencies #include "QCamera2HWI.h" #include "QCameraTrace.h" @@ -1371,7 +1368,7 @@ void QCamera2HardwareInterface::video_stream_cb_routine(mm_camera_super_buf_t *s void *userdata) { ATRACE_CALL(); - QCameraMemory *videoMemObj = NULL; + QCameraVideoMemory *videoMemObj = NULL; camera_memory_t *video_mem = NULL; nsecs_t timeStamp = 0; bool triggerTCB = FALSE; @@ -1408,11 +1405,12 @@ void QCamera2HardwareInterface::video_stream_cb_routine(mm_camera_super_buf_t *s LOGD("Video frame to encoder TimeStamp : %lld batch = 0", timeStamp); pme->dumpFrameToFile(stream, frame, QCAMERA_DUMP_FRM_VIDEO); - videoMemObj = (QCameraMemory *)frame->mem_info; + videoMemObj = (QCameraVideoMemory *)frame->mem_info; video_mem = NULL; if (NULL != videoMemObj) { video_mem = videoMemObj->getMemory(frame->buf_idx, (pme->mStoreMetaDataInFrame > 0)? true : false); + videoMemObj->updateNativeHandle(frame->buf_idx); triggerTCB = TRUE; } } else { @@ -1434,7 +1432,8 @@ void QCamera2HardwareInterface::video_stream_cb_routine(mm_camera_super_buf_t *s } } video_mem = stream->mCurMetaMemory; - if (video_mem == NULL) { + nh = videoMemObj->updateNativeHandle(stream->mCurMetaIndex); + if (video_mem == NULL || nh == NULL) { LOGE("No Free metadata. Drop this frame"); stream->mCurBufIndex = -1; stream->bufDone(frame->buf_idx); @@ -1442,9 +1441,6 @@ void QCamera2HardwareInterface::video_stream_cb_routine(mm_camera_super_buf_t *s return; } - struct encoder_media_buffer_type * packet = - (struct encoder_media_buffer_type *)video_mem->data; - nh = const_cast(packet->meta_handle); int index = stream->mCurBufIndex; int fd_cnt = pme->mParameters.getVideoBatchSize(); nsecs_t frame_ts = nsecs_t(frame->ts.tv_sec) * 1000000000LL @@ -1484,19 +1480,13 @@ void QCamera2HardwareInterface::video_stream_cb_routine(mm_camera_super_buf_t *s } } } else { - videoMemObj = (QCameraMemory *)frame->mem_info; + videoMemObj = (QCameraVideoMemory *)frame->mem_info; video_mem = NULL; native_handle_t *nh = NULL; int fd_cnt = frame->user_buf.bufs_used; if (NULL != videoMemObj) { video_mem = videoMemObj->getMemory(frame->buf_idx, true); - if (video_mem != NULL) { - struct encoder_media_buffer_type * packet = - (struct encoder_media_buffer_type *)video_mem->data; - nh = const_cast(packet->meta_handle); - } else { - LOGE("video_mem NULL"); - } + nh = videoMemObj->updateNativeHandle(frame->buf_idx); } else { LOGE("videoMemObj NULL"); } diff --git a/camera/QCamera2/HAL/QCameraMem.cpp b/camera/QCamera2/HAL/QCameraMem.cpp old mode 100644 new mode 100755 index c603726..0a1f697 --- a/camera/QCamera2/HAL/QCameraMem.cpp +++ b/camera/QCamera2/HAL/QCameraMem.cpp @@ -37,16 +37,22 @@ #include "gralloc.h" #include "gralloc_priv.h" -// OpenMAX dependencies -#include "OMX_QCOMExtns.h" -#include "QComOMXMetadata.h" - // Camera dependencies #include "QCamera2HWI.h" #include "QCameraMem.h" #include "QCameraParameters.h" #include "QCameraTrace.h" +// Media dependencies +#include "OMX_QCOMExtns.h" +#ifdef USE_MEDIA_EXTENSIONS +#include +typedef struct VideoNativeHandleMetadata media_metadata_buffer; +#else +#include "QComOMXMetadata.h" +typedef struct encoder_media_buffer_type media_metadata_buffer; +#endif + extern "C" { #include "mm_camera_dbg.h" #include "mm_camera_interface.h" @@ -1279,6 +1285,7 @@ QCameraVideoMemory::QCameraVideoMemory(camera_request_memory memory, : QCameraStreamMemory(memory, cached) { memset(mMetadata, 0, sizeof(mMetadata)); + memset(mNativeHandle, 0, sizeof(mNativeHandle)); mMetaBufCount = 0; mBufType = bufType; //Set Default color conversion format @@ -1334,9 +1341,7 @@ int QCameraVideoMemory::allocate(uint8_t count, size_t size, uint32_t isSecure) return rc; } for (int i = 0; i < count; i ++) { - struct encoder_media_buffer_type * packet = - (struct encoder_media_buffer_type *)mMetadata[i]->data; - native_handle_t * nh = const_cast(packet->meta_handle); + native_handle_t *nh = mNativeHandle[i]; if (!nh) { LOGE("Error in getting video native handle"); ATRACE_END(); @@ -1380,7 +1385,7 @@ int QCameraVideoMemory::allocateMore(uint8_t count, size_t size) if (!(mBufType & QCAMERA_MEM_TYPE_BATCH)) { for (int i = mBufferCount; i < count + mBufferCount; i ++) { mMetadata[i] = mGetMemory(-1, - sizeof(struct encoder_media_buffer_type), 1, this); + sizeof(media_metadata_buffer), 1, this); if (!mMetadata[i]) { LOGE("allocation of video metadata failed."); for (int j = mBufferCount; j <= i-1; j ++) { @@ -1392,14 +1397,19 @@ int QCameraVideoMemory::allocateMore(uint8_t count, size_t size) ATRACE_END(); return NO_MEMORY; } - struct encoder_media_buffer_type * packet = - (struct encoder_media_buffer_type *)mMetadata[i]->data; - + media_metadata_buffer * packet = + (media_metadata_buffer *)mMetadata[i]->data; //FDs = 1 //numInts = 5 (offset, size, usage, timestamp, format) - packet->meta_handle = native_handle_create(1, VIDEO_METADATA_NUM_INTS); + mNativeHandle[i] = native_handle_create(1, VIDEO_METADATA_NUM_INTS); +#ifdef USE_MEDIA_EXTENSIONS + packet->eType = kMetadataBufferTypeNativeHandleSource; + packet->pHandle = mNativeHandle[i]; +#else packet->buffer_type = kMetadataBufferTypeCameraSource; - native_handle_t * nh = const_cast(packet->meta_handle); + packet->meta_handle = mNativeHandle[i]; +#endif + native_handle_t *nh = mNativeHandle[i]; if (!nh) { LOGE("Error in getting video native handle"); ATRACE_END(); @@ -1437,25 +1447,38 @@ int QCameraVideoMemory::allocateMeta(uint8_t buf_cnt, int numFDs, int numInts) for (int i = 0; i < buf_cnt; i++) { mMetadata[i] = mGetMemory(-1, - sizeof(struct encoder_media_buffer_type), 1, this); + sizeof(media_metadata_buffer), 1, this); if (!mMetadata[i]) { LOGE("allocation of video metadata failed."); for (int j = (i - 1); j >= 0; j--) { + if (NULL != mNativeHandle[j]) { + native_handle_delete(mNativeHandle[j]); + } mMetadata[j]->release(mMetadata[j]); } return NO_MEMORY; } - struct encoder_media_buffer_type * packet = - (struct encoder_media_buffer_type *)mMetadata[i]->data; - packet->meta_handle = native_handle_create(numFDs, (numInts * numFDs)); - packet->buffer_type = kMetadataBufferTypeCameraSource; - if (packet->meta_handle == NULL) { + media_metadata_buffer *packet = + (media_metadata_buffer *)mMetadata[i]->data; + mNativeHandle[i] = native_handle_create(numFDs, (numInts * numFDs)); + if (mNativeHandle[i] == NULL) { LOGE("Error in getting video native handle"); for (int j = (i - 1); j >= 0; j--) { + mMetadata[i]->release(mMetadata[i]); + if (NULL != mNativeHandle[j]) { + native_handle_delete(mNativeHandle[j]); + } mMetadata[j]->release(mMetadata[j]); } return NO_MEMORY; } +#ifdef USE_MEDIA_EXTENSIONS + packet->eType = kMetadataBufferTypeNativeHandleSource; + packet->pHandle = mNativeHandle[i]; +#else + packet->buffer_type = kMetadataBufferTypeCameraSource; + packet->meta_handle = mNativeHandle[i]; +#endif } mMetaBufCount = buf_cnt; return rc; @@ -1473,20 +1496,15 @@ int QCameraVideoMemory::allocateMeta(uint8_t buf_cnt, int numFDs, int numInts) void QCameraVideoMemory::deallocateMeta() { for (int i = 0; i < mMetaBufCount; i++) { - struct encoder_media_buffer_type * packet = - (struct encoder_media_buffer_type *)mMetadata[i]->data; - if (NULL != packet) { - native_handle_t * nh = const_cast(packet->meta_handle); - if (NULL != nh) { - if (native_handle_delete(nh)) { - LOGE("Unable to delete native handle"); - } - } else { - LOGE("native handle not available"); - } + native_handle_t *nh = mNativeHandle[i]; + if (NULL != nh) { + if (native_handle_delete(nh)) { + LOGE("Unable to delete native handle"); + } } else { - LOGE("packet not available"); + LOGE("native handle not available"); } + mNativeHandle[i] = NULL; mMetadata[i]->release(mMetadata[i]); mMetadata[i] = NULL; } @@ -1536,6 +1554,77 @@ camera_memory_t *QCameraVideoMemory::getMemory(uint32_t index, return mCameraMemory[index]; } +/*=========================================================================== + * FUNCTION : updateNativeHandle + * + * DESCRIPTION: Updating native handle pointer + * + * PARAMETERS : + * @index : buffer index + * @metadata: flag if it's metadata + * + * RETURN : camera native handle ptr + * NULL if not supported or failed + *==========================================================================*/ +native_handle_t *QCameraVideoMemory::updateNativeHandle(uint32_t index, bool metadata) +{ + if (index >= mMetaBufCount || (!metadata && index >= mBufferCount)) { + return NULL; + } + + native_handle_t *nh = NULL; + if (metadata && mMetadata[index] != NULL) { + media_metadata_buffer *packet = + (media_metadata_buffer *)mMetadata[index]->data; + nh = mNativeHandle[index]; +#ifdef USE_MEDIA_EXTENSIONS + packet->pHandle = nh; +#else + packet->meta_handle = nh; +#endif + } + return nh; +} + +/*=========================================================================== + * FUNCTION : closeNativeHandle + * + * DESCRIPTION: close video native handle + * + * PARAMETERS : + * @opaque : ptr to video frame to be returned + * + * RETURN : int32_t type of status + * NO_ERROR -- success + * none-zero failure code + *==========================================================================*/ +int QCameraVideoMemory::closeNativeHandle(const void *data, bool metadata) +{ + int32_t rc = NO_ERROR; + +#ifdef USE_MEDIA_EXTENSIONS + camera_memory_t *video_mem = (camera_memory_t *)data; + + if(video_mem == NULL) { + LOGE("video_mem NULL. Failed"); + return BAD_VALUE; + } + if (metadata) { + media_metadata_buffer *packet = + (media_metadata_buffer *)video_mem->data; + if (packet->eType == kMetadataBufferTypeNativeHandleSource) { + native_handle_close(packet->pHandle); + native_handle_delete(packet->pHandle); + packet->pHandle = NULL; + } + } else { + LOGE("Not of type video meta buffer. Failed"); + return BAD_VALUE; + } +#endif + return rc; +} + /*=========================================================================== * FUNCTION : getMatchBufIndex * diff --git a/camera/QCamera2/HAL/QCameraMem.h b/camera/QCamera2/HAL/QCameraMem.h index 2b99668..21bc36a 100644 --- a/camera/QCamera2/HAL/QCameraMem.h +++ b/camera/QCamera2/HAL/QCameraMem.h @@ -231,10 +231,13 @@ public: int getUsage(){return mUsage;}; int getFormat(){return mFormat;}; int convCamtoOMXFormat(cam_format_t format); + native_handle_t *updateNativeHandle(uint32_t index, bool metadata = true); + static int closeNativeHandle(const void *data, bool metadata = true); private: camera_memory_t *mMetadata[MM_CAMERA_MAX_NUM_FRAMES]; uint8_t mMetaBufCount; int mUsage, mFormat; + native_handle_t *mNativeHandle[MM_CAMERA_MAX_NUM_FRAMES]; };