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
This commit is contained in:
Guruprasad Gaonkar 2016-04-05 19:03:59 -07:00 committed by Prateek Chaubey
parent 015dd92754
commit 3dd1d4cba8
5 changed files with 141 additions and 50 deletions

View file

@ -50,6 +50,11 @@ ifeq ($(TARGET_USES_AOSP),true)
LOCAL_CFLAGS += -DVANILLA_HAL LOCAL_CFLAGS += -DVANILLA_HAL
endif endif
#use media extension
ifeq ($(TARGET_USES_MEDIA_EXTENSIONS), true)
LOCAL_CFLAGS += -DUSE_MEDIA_EXTENSIONS
endif
#HAL 1.0 Flags #HAL 1.0 Flags
LOCAL_CFLAGS += -DDEFAULT_DENOISE_MODE_ON -DHAL3 -DQCAMERA_REDEFINE_LOG 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 $(BUILD_SHARED_LIBRARY)
include $(call first-makefiles-under,$(LOCAL_PATH)) include $(call first-makefiles-under,$(LOCAL_PATH))
endif endif

View file

@ -775,6 +775,10 @@ void QCamera2HardwareInterface::release_recording_frame(
return; return;
} }
LOGD("E camera id %d", hw->getCameraId()); LOGD("E camera id %d", hw->getCameraId());
//Close and delete duplicated native handle and FD's.
QCameraVideoMemory::closeNativeHandle(opaque, hw->mStoreMetaDataInFrame > 0);
hw->lockAPI(); hw->lockAPI();
qcamera_api_result_t apiResult; qcamera_api_result_t apiResult;
int32_t ret = hw->processAPI(QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME, (void *)opaque); 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; int32_t rc = UNKNOWN_ERROR;
QCameraVideoChannel *pChannel = QCameraVideoChannel *pChannel =
(QCameraVideoChannel *)m_channels[QCAMERA_CH_TYPE_VIDEO]; (QCameraVideoChannel *)m_channels[QCAMERA_CH_TYPE_VIDEO];
LOGD("opaque data = %p",opaque); LOGD("opaque data = %p",opaque);
if(pChannel != NULL) { if(pChannel != NULL) {
rc = pChannel->releaseFrame(opaque, mStoreMetaDataInFrame > 0); rc = pChannel->releaseFrame(opaque, mStoreMetaDataInFrame > 0);
} }

View file

@ -37,9 +37,6 @@
#include STAT_H #include STAT_H
#include <utils/Errors.h> #include <utils/Errors.h>
// OpenMAX dependencies
#include "QComOMXMetadata.h"
// Camera dependencies // Camera dependencies
#include "QCamera2HWI.h" #include "QCamera2HWI.h"
#include "QCameraTrace.h" #include "QCameraTrace.h"
@ -1371,7 +1368,7 @@ void QCamera2HardwareInterface::video_stream_cb_routine(mm_camera_super_buf_t *s
void *userdata) void *userdata)
{ {
ATRACE_CALL(); ATRACE_CALL();
QCameraMemory *videoMemObj = NULL; QCameraVideoMemory *videoMemObj = NULL;
camera_memory_t *video_mem = NULL; camera_memory_t *video_mem = NULL;
nsecs_t timeStamp = 0; nsecs_t timeStamp = 0;
bool triggerTCB = FALSE; 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", LOGD("Video frame to encoder TimeStamp : %lld batch = 0",
timeStamp); timeStamp);
pme->dumpFrameToFile(stream, frame, QCAMERA_DUMP_FRM_VIDEO); pme->dumpFrameToFile(stream, frame, QCAMERA_DUMP_FRM_VIDEO);
videoMemObj = (QCameraMemory *)frame->mem_info; videoMemObj = (QCameraVideoMemory *)frame->mem_info;
video_mem = NULL; video_mem = NULL;
if (NULL != videoMemObj) { if (NULL != videoMemObj) {
video_mem = videoMemObj->getMemory(frame->buf_idx, video_mem = videoMemObj->getMemory(frame->buf_idx,
(pme->mStoreMetaDataInFrame > 0)? true : false); (pme->mStoreMetaDataInFrame > 0)? true : false);
videoMemObj->updateNativeHandle(frame->buf_idx);
triggerTCB = TRUE; triggerTCB = TRUE;
} }
} else { } else {
@ -1434,7 +1432,8 @@ void QCamera2HardwareInterface::video_stream_cb_routine(mm_camera_super_buf_t *s
} }
} }
video_mem = stream->mCurMetaMemory; 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"); LOGE("No Free metadata. Drop this frame");
stream->mCurBufIndex = -1; stream->mCurBufIndex = -1;
stream->bufDone(frame->buf_idx); stream->bufDone(frame->buf_idx);
@ -1442,9 +1441,6 @@ void QCamera2HardwareInterface::video_stream_cb_routine(mm_camera_super_buf_t *s
return; return;
} }
struct encoder_media_buffer_type * packet =
(struct encoder_media_buffer_type *)video_mem->data;
nh = const_cast<native_handle_t *>(packet->meta_handle);
int index = stream->mCurBufIndex; int index = stream->mCurBufIndex;
int fd_cnt = pme->mParameters.getVideoBatchSize(); int fd_cnt = pme->mParameters.getVideoBatchSize();
nsecs_t frame_ts = nsecs_t(frame->ts.tv_sec) * 1000000000LL 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 { } else {
videoMemObj = (QCameraMemory *)frame->mem_info; videoMemObj = (QCameraVideoMemory *)frame->mem_info;
video_mem = NULL; video_mem = NULL;
native_handle_t *nh = NULL; native_handle_t *nh = NULL;
int fd_cnt = frame->user_buf.bufs_used; int fd_cnt = frame->user_buf.bufs_used;
if (NULL != videoMemObj) { if (NULL != videoMemObj) {
video_mem = videoMemObj->getMemory(frame->buf_idx, true); video_mem = videoMemObj->getMemory(frame->buf_idx, true);
if (video_mem != NULL) { nh = videoMemObj->updateNativeHandle(frame->buf_idx);
struct encoder_media_buffer_type * packet =
(struct encoder_media_buffer_type *)video_mem->data;
nh = const_cast<native_handle_t *>(packet->meta_handle);
} else {
LOGE("video_mem NULL");
}
} else { } else {
LOGE("videoMemObj NULL"); LOGE("videoMemObj NULL");
} }

151
camera/QCamera2/HAL/QCameraMem.cpp Normal file → Executable file
View file

@ -37,16 +37,22 @@
#include "gralloc.h" #include "gralloc.h"
#include "gralloc_priv.h" #include "gralloc_priv.h"
// OpenMAX dependencies
#include "OMX_QCOMExtns.h"
#include "QComOMXMetadata.h"
// Camera dependencies // Camera dependencies
#include "QCamera2HWI.h" #include "QCamera2HWI.h"
#include "QCameraMem.h" #include "QCameraMem.h"
#include "QCameraParameters.h" #include "QCameraParameters.h"
#include "QCameraTrace.h" #include "QCameraTrace.h"
// Media dependencies
#include "OMX_QCOMExtns.h"
#ifdef USE_MEDIA_EXTENSIONS
#include <media/hardware/HardwareAPI.h>
typedef struct VideoNativeHandleMetadata media_metadata_buffer;
#else
#include "QComOMXMetadata.h"
typedef struct encoder_media_buffer_type media_metadata_buffer;
#endif
extern "C" { extern "C" {
#include "mm_camera_dbg.h" #include "mm_camera_dbg.h"
#include "mm_camera_interface.h" #include "mm_camera_interface.h"
@ -1279,6 +1285,7 @@ QCameraVideoMemory::QCameraVideoMemory(camera_request_memory memory,
: QCameraStreamMemory(memory, cached) : QCameraStreamMemory(memory, cached)
{ {
memset(mMetadata, 0, sizeof(mMetadata)); memset(mMetadata, 0, sizeof(mMetadata));
memset(mNativeHandle, 0, sizeof(mNativeHandle));
mMetaBufCount = 0; mMetaBufCount = 0;
mBufType = bufType; mBufType = bufType;
//Set Default color conversion format //Set Default color conversion format
@ -1334,9 +1341,7 @@ int QCameraVideoMemory::allocate(uint8_t count, size_t size, uint32_t isSecure)
return rc; return rc;
} }
for (int i = 0; i < count; i ++) { for (int i = 0; i < count; i ++) {
struct encoder_media_buffer_type * packet = native_handle_t *nh = mNativeHandle[i];
(struct encoder_media_buffer_type *)mMetadata[i]->data;
native_handle_t * nh = const_cast<native_handle_t *>(packet->meta_handle);
if (!nh) { if (!nh) {
LOGE("Error in getting video native handle"); LOGE("Error in getting video native handle");
ATRACE_END(); ATRACE_END();
@ -1380,7 +1385,7 @@ int QCameraVideoMemory::allocateMore(uint8_t count, size_t size)
if (!(mBufType & QCAMERA_MEM_TYPE_BATCH)) { if (!(mBufType & QCAMERA_MEM_TYPE_BATCH)) {
for (int i = mBufferCount; i < count + mBufferCount; i ++) { for (int i = mBufferCount; i < count + mBufferCount; i ++) {
mMetadata[i] = mGetMemory(-1, mMetadata[i] = mGetMemory(-1,
sizeof(struct encoder_media_buffer_type), 1, this); sizeof(media_metadata_buffer), 1, this);
if (!mMetadata[i]) { if (!mMetadata[i]) {
LOGE("allocation of video metadata failed."); LOGE("allocation of video metadata failed.");
for (int j = mBufferCount; j <= i-1; j ++) { for (int j = mBufferCount; j <= i-1; j ++) {
@ -1392,14 +1397,19 @@ int QCameraVideoMemory::allocateMore(uint8_t count, size_t size)
ATRACE_END(); ATRACE_END();
return NO_MEMORY; return NO_MEMORY;
} }
struct encoder_media_buffer_type * packet = media_metadata_buffer * packet =
(struct encoder_media_buffer_type *)mMetadata[i]->data; (media_metadata_buffer *)mMetadata[i]->data;
//FDs = 1 //FDs = 1
//numInts = 5 (offset, size, usage, timestamp, format) //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; packet->buffer_type = kMetadataBufferTypeCameraSource;
native_handle_t * nh = const_cast<native_handle_t *>(packet->meta_handle); packet->meta_handle = mNativeHandle[i];
#endif
native_handle_t *nh = mNativeHandle[i];
if (!nh) { if (!nh) {
LOGE("Error in getting video native handle"); LOGE("Error in getting video native handle");
ATRACE_END(); 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++) { for (int i = 0; i < buf_cnt; i++) {
mMetadata[i] = mGetMemory(-1, mMetadata[i] = mGetMemory(-1,
sizeof(struct encoder_media_buffer_type), 1, this); sizeof(media_metadata_buffer), 1, this);
if (!mMetadata[i]) { if (!mMetadata[i]) {
LOGE("allocation of video metadata failed."); LOGE("allocation of video metadata failed.");
for (int j = (i - 1); j >= 0; j--) { for (int j = (i - 1); j >= 0; j--) {
if (NULL != mNativeHandle[j]) {
native_handle_delete(mNativeHandle[j]);
}
mMetadata[j]->release(mMetadata[j]); mMetadata[j]->release(mMetadata[j]);
} }
return NO_MEMORY; return NO_MEMORY;
} }
struct encoder_media_buffer_type * packet = media_metadata_buffer *packet =
(struct encoder_media_buffer_type *)mMetadata[i]->data; (media_metadata_buffer *)mMetadata[i]->data;
packet->meta_handle = native_handle_create(numFDs, (numInts * numFDs)); mNativeHandle[i] = native_handle_create(numFDs, (numInts * numFDs));
packet->buffer_type = kMetadataBufferTypeCameraSource; if (mNativeHandle[i] == NULL) {
if (packet->meta_handle == NULL) {
LOGE("Error in getting video native handle"); LOGE("Error in getting video native handle");
for (int j = (i - 1); j >= 0; j--) { 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]); mMetadata[j]->release(mMetadata[j]);
} }
return NO_MEMORY; 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; mMetaBufCount = buf_cnt;
return rc; return rc;
@ -1473,20 +1496,15 @@ int QCameraVideoMemory::allocateMeta(uint8_t buf_cnt, int numFDs, int numInts)
void QCameraVideoMemory::deallocateMeta() void QCameraVideoMemory::deallocateMeta()
{ {
for (int i = 0; i < mMetaBufCount; i++) { for (int i = 0; i < mMetaBufCount; i++) {
struct encoder_media_buffer_type * packet = native_handle_t *nh = mNativeHandle[i];
(struct encoder_media_buffer_type *)mMetadata[i]->data; if (NULL != nh) {
if (NULL != packet) { if (native_handle_delete(nh)) {
native_handle_t * nh = const_cast<native_handle_t *>(packet->meta_handle); LOGE("Unable to delete native handle");
if (NULL != nh) { }
if (native_handle_delete(nh)) {
LOGE("Unable to delete native handle");
}
} else {
LOGE("native handle not available");
}
} else { } else {
LOGE("packet not available"); LOGE("native handle not available");
} }
mNativeHandle[i] = NULL;
mMetadata[i]->release(mMetadata[i]); mMetadata[i]->release(mMetadata[i]);
mMetadata[i] = NULL; mMetadata[i] = NULL;
} }
@ -1536,6 +1554,77 @@ camera_memory_t *QCameraVideoMemory::getMemory(uint32_t index,
return mCameraMemory[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 * FUNCTION : getMatchBufIndex
* *

View file

@ -231,10 +231,13 @@ public:
int getUsage(){return mUsage;}; int getUsage(){return mUsage;};
int getFormat(){return mFormat;}; int getFormat(){return mFormat;};
int convCamtoOMXFormat(cam_format_t format); 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: private:
camera_memory_t *mMetadata[MM_CAMERA_MAX_NUM_FRAMES]; camera_memory_t *mMetadata[MM_CAMERA_MAX_NUM_FRAMES];
uint8_t mMetaBufCount; uint8_t mMetaBufCount;
int mUsage, mFormat; int mUsage, mFormat;
native_handle_t *mNativeHandle[MM_CAMERA_MAX_NUM_FRAMES];
}; };