QCamera2: Add buffer identity for video native handle.
Issue: Release_recording() can be called with any Imemory pointer sent earlier. HAL cannot use this pointer to recognize video frame to match before release this buffer to kernel. Fix: Buffer identity is introduced to every video buffer and released buffer can be found by comparing identity. CRs-Fixed: 1026840 Change-Id: I287d1276fbf2241a2fc6d470e887a91e1daeca4d
This commit is contained in:
parent
665ea6feed
commit
c93f5696c8
6 changed files with 105 additions and 80 deletions
|
@ -703,7 +703,6 @@ void QCamera2HardwareInterface::stop_recording(struct camera_device *device)
|
|||
|
||||
// Disable power hint for video encoding
|
||||
hw->m_perfLock.powerHint(POWER_HINT_VIDEO_ENCODE, false);
|
||||
mVideoMem = NULL;
|
||||
|
||||
hw->lockAPI();
|
||||
qcamera_api_result_t apiResult;
|
||||
|
@ -778,17 +777,6 @@ void QCamera2HardwareInterface::release_recording_frame(
|
|||
}
|
||||
LOGD("E camera id %d", hw->getCameraId());
|
||||
|
||||
//Close and delete duplicated native handle and FD's.
|
||||
if ((hw->mVideoMem != NULL) && (hw->mStoreMetaDataInFrame)) {
|
||||
ret = hw->mVideoMem->closeNativeHandle(opaque, TRUE);
|
||||
if (ret != NO_ERROR) {
|
||||
LOGE("Invalid video metadata");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
LOGW("Possible FD leak. Release recording called after stop");
|
||||
}
|
||||
|
||||
hw->lockAPI();
|
||||
qcamera_api_result_t apiResult;
|
||||
ret = hw->processAPI(QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME, (void *)opaque);
|
||||
|
@ -1681,7 +1669,6 @@ QCamera2HardwareInterface::QCamera2HardwareInterface(uint32_t cameraId)
|
|||
mJpegClientHandle(0),
|
||||
mJpegHandleOwner(false),
|
||||
mMetadataMem(NULL),
|
||||
mVideoMem(NULL),
|
||||
mCACDoneReceived(false),
|
||||
m_bNeedRestart(false),
|
||||
mIgnoredPreviewCount(0)
|
||||
|
@ -2822,10 +2809,6 @@ QCameraMemory *QCamera2HardwareInterface::allocateStreamBuf(
|
|||
}
|
||||
videoMemory->setVideoInfo(usage, fmt);
|
||||
mem = videoMemory;
|
||||
if (!mParameters.getBufBatchCount()) {
|
||||
//For batch mode this will be part of user buffer.
|
||||
mVideoMem = videoMemory;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CAM_STREAM_TYPE_CALLBACK:
|
||||
|
@ -3157,7 +3140,6 @@ QCameraMemory *QCamera2HardwareInterface::allocateStreamUserBuf(
|
|||
}
|
||||
video_mem->setVideoInfo(usage, fmt);
|
||||
mem = static_cast<QCameraMemory *>(video_mem);
|
||||
mVideoMem = video_mem;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -3594,7 +3576,6 @@ int QCamera2HardwareInterface::startRecording()
|
|||
int32_t rc = NO_ERROR;
|
||||
|
||||
LOGI("E");
|
||||
mVideoMem = NULL;
|
||||
//link meta stream with video channel if low power mode.
|
||||
if (isLowPowerMode()) {
|
||||
// Find and try to link a metadata stream from preview channel
|
||||
|
|
|
@ -745,7 +745,6 @@ private:
|
|||
bool TsMakeupProcess(mm_camera_buf_def_t *frame,QCameraStream * stream,TSRect& faceRect);
|
||||
#endif
|
||||
QCameraMemory *mMetadataMem;
|
||||
QCameraVideoMemory *mVideoMem;
|
||||
|
||||
static uint32_t sNextJobId;
|
||||
|
||||
|
|
|
@ -1373,7 +1373,7 @@ void QCamera2HardwareInterface::video_stream_cb_routine(mm_camera_super_buf_t *s
|
|||
nsecs_t timeStamp = 0;
|
||||
bool triggerTCB = FALSE;
|
||||
|
||||
LOGH("[KPI Perf] : BEGIN");
|
||||
LOGD("[KPI Perf] : BEGIN");
|
||||
QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata;
|
||||
if (pme == NULL ||
|
||||
pme->mCameraHandle == NULL ||
|
||||
|
@ -1402,16 +1402,15 @@ void QCamera2HardwareInterface::video_stream_cb_routine(mm_camera_super_buf_t *s
|
|||
if (pme->mParameters.getVideoBatchSize() == 0) {
|
||||
timeStamp = nsecs_t(frame->ts.tv_sec) * 1000000000LL
|
||||
+ frame->ts.tv_nsec;
|
||||
LOGD("Video frame to encoder TimeStamp : %lld batch = 0",
|
||||
timeStamp);
|
||||
pme->dumpFrameToFile(stream, frame, QCAMERA_DUMP_FRM_VIDEO);
|
||||
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;
|
||||
LOGH("Video frame TimeStamp : %lld batch = 0 index = %d",
|
||||
timeStamp, frame->buf_idx);
|
||||
}
|
||||
} else {
|
||||
//Handle video batch callback
|
||||
|
@ -1432,7 +1431,7 @@ void QCamera2HardwareInterface::video_stream_cb_routine(mm_camera_super_buf_t *s
|
|||
}
|
||||
}
|
||||
video_mem = stream->mCurMetaMemory;
|
||||
nh = videoMemObj->updateNativeHandle(stream->mCurMetaIndex);
|
||||
nh = videoMemObj->getNativeHandle(stream->mCurMetaIndex);
|
||||
if (video_mem == NULL || nh == NULL) {
|
||||
LOGE("No Free metadata. Drop this frame");
|
||||
stream->mCurBufIndex = -1;
|
||||
|
@ -1471,8 +1470,9 @@ void QCamera2HardwareInterface::video_stream_cb_routine(mm_camera_super_buf_t *s
|
|||
stream->mCurBufIndex++;
|
||||
if (stream->mCurBufIndex == fd_cnt) {
|
||||
timeStamp = stream->mFirstTimeStamp;
|
||||
LOGD("Video frame to encoder TimeStamp : %lld batch = %d",
|
||||
timeStamp, fd_cnt);
|
||||
LOGH("Video frame to encoder TimeStamp : %lld batch = %d Buffer idx = %d",
|
||||
timeStamp, fd_cnt,
|
||||
nh->data[nh->numFds + nh->numInts - VIDEO_METADATA_NUM_COMMON_INTS]);
|
||||
stream->mCurBufIndex = -1;
|
||||
stream->mCurMetaIndex = -1;
|
||||
stream->mCurMetaMemory = NULL;
|
||||
|
@ -1486,7 +1486,7 @@ void QCamera2HardwareInterface::video_stream_cb_routine(mm_camera_super_buf_t *s
|
|||
int fd_cnt = frame->user_buf.bufs_used;
|
||||
if (NULL != videoMemObj) {
|
||||
video_mem = videoMemObj->getMemory(frame->buf_idx, true);
|
||||
nh = videoMemObj->updateNativeHandle(frame->buf_idx);
|
||||
nh = videoMemObj->getNativeHandle(frame->buf_idx);
|
||||
} else {
|
||||
LOGE("videoMemObj NULL");
|
||||
}
|
||||
|
@ -1494,8 +1494,6 @@ void QCamera2HardwareInterface::video_stream_cb_routine(mm_camera_super_buf_t *s
|
|||
if (nh != NULL) {
|
||||
timeStamp = nsecs_t(frame->ts.tv_sec) * 1000000000LL
|
||||
+ frame->ts.tv_nsec;
|
||||
LOGD("Batch buffer TimeStamp : %lld FD = %d index = %d fd_cnt = %d",
|
||||
timeStamp, frame->fd, frame->buf_idx, fd_cnt);
|
||||
|
||||
for (int i = 0; i < fd_cnt; i++) {
|
||||
if (frame->user_buf.buf_idx[i] >= 0) {
|
||||
|
@ -1526,6 +1524,8 @@ void QCamera2HardwareInterface::video_stream_cb_routine(mm_camera_super_buf_t *s
|
|||
}
|
||||
}
|
||||
triggerTCB = TRUE;
|
||||
LOGH("Batch buffer TimeStamp : %lld FD = %d index = %d fd_cnt = %d",
|
||||
timeStamp, frame->fd, frame->buf_idx, fd_cnt);
|
||||
} else {
|
||||
LOGE("No Video Meta Available. Return Buffer");
|
||||
stream->bufDone(super_frame->bufs[0]->buf_idx);
|
||||
|
@ -1550,7 +1550,7 @@ void QCamera2HardwareInterface::video_stream_cb_routine(mm_camera_super_buf_t *s
|
|||
}
|
||||
|
||||
free(super_frame);
|
||||
LOGH("[KPI Perf] : END");
|
||||
LOGD("[KPI Perf] : END");
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
|
|
|
@ -1333,7 +1333,7 @@ int QCameraVideoMemory::allocate(uint8_t count, size_t size, uint32_t isSecure)
|
|||
if (!(mBufType & QCAMERA_MEM_TYPE_BATCH)) {
|
||||
/*
|
||||
* FDs = 1
|
||||
* numInts = 5 //offset, size, usage, timestamp, format
|
||||
* numInts = 5 //offset, size, usage, timestamp, format + 1 for buffer index
|
||||
*/
|
||||
rc = allocateMeta(count, 1, VIDEO_METADATA_NUM_INTS);
|
||||
if (rc != NO_ERROR) {
|
||||
|
@ -1401,10 +1401,11 @@ int QCameraVideoMemory::allocateMore(uint8_t count, size_t size)
|
|||
(media_metadata_buffer *)mMetadata[i]->data;
|
||||
//FDs = 1
|
||||
//numInts = 5 (offset, size, usage, timestamp, format)
|
||||
mNativeHandle[i] = native_handle_create(1, VIDEO_METADATA_NUM_INTS);
|
||||
mNativeHandle[i] = native_handle_create(1,
|
||||
(VIDEO_METADATA_NUM_INTS + VIDEO_METADATA_NUM_COMMON_INTS));
|
||||
#ifdef USE_MEDIA_EXTENSIONS
|
||||
packet->eType = kMetadataBufferTypeNativeHandleSource;
|
||||
packet->pHandle = mNativeHandle[i];
|
||||
packet->pHandle = NULL;
|
||||
#else
|
||||
packet->buffer_type = kMetadataBufferTypeCameraSource;
|
||||
packet->meta_handle = mNativeHandle[i];
|
||||
|
@ -1421,6 +1422,7 @@ int QCameraVideoMemory::allocateMore(uint8_t count, size_t size)
|
|||
nh->data[3] = mUsage;
|
||||
nh->data[4] = 0; //dummy value for timestamp in non-batch mode
|
||||
nh->data[5] = mFormat;
|
||||
nh->data[6] = i;
|
||||
}
|
||||
}
|
||||
mBufferCount = (uint8_t)(mBufferCount + count);
|
||||
|
@ -1444,6 +1446,7 @@ int QCameraVideoMemory::allocateMore(uint8_t count, size_t size)
|
|||
int QCameraVideoMemory::allocateMeta(uint8_t buf_cnt, int numFDs, int numInts)
|
||||
{
|
||||
int rc = NO_ERROR;
|
||||
int mTotalInts = 0;
|
||||
|
||||
for (int i = 0; i < buf_cnt; i++) {
|
||||
mMetadata[i] = mGetMemory(-1,
|
||||
|
@ -1460,7 +1463,9 @@ int QCameraVideoMemory::allocateMeta(uint8_t buf_cnt, int numFDs, int numInts)
|
|||
}
|
||||
media_metadata_buffer *packet =
|
||||
(media_metadata_buffer *)mMetadata[i]->data;
|
||||
mNativeHandle[i] = native_handle_create(numFDs, (numInts * numFDs));
|
||||
mTotalInts = (numInts * numFDs);
|
||||
mNativeHandle[i] = native_handle_create(numFDs,
|
||||
(mTotalInts + VIDEO_METADATA_NUM_COMMON_INTS));
|
||||
if (mNativeHandle[i] == NULL) {
|
||||
LOGE("Error in getting video native handle");
|
||||
for (int j = (i - 1); j >= 0; j--) {
|
||||
|
@ -1471,10 +1476,14 @@ int QCameraVideoMemory::allocateMeta(uint8_t buf_cnt, int numFDs, int numInts)
|
|||
mMetadata[j]->release(mMetadata[j]);
|
||||
}
|
||||
return NO_MEMORY;
|
||||
} else {
|
||||
//assign buffer index to native handle.
|
||||
native_handle_t *nh = mNativeHandle[i];
|
||||
nh->data[numFDs + mTotalInts] = i;
|
||||
}
|
||||
#ifdef USE_MEDIA_EXTENSIONS
|
||||
packet->eType = kMetadataBufferTypeNativeHandleSource;
|
||||
packet->pHandle = mNativeHandle[i];
|
||||
packet->pHandle = NULL;
|
||||
#else
|
||||
packet->buffer_type = kMetadataBufferTypeCameraSource;
|
||||
packet->meta_handle = mNativeHandle[i];
|
||||
|
@ -1545,54 +1554,59 @@ void QCameraVideoMemory::deallocate()
|
|||
camera_memory_t *QCameraVideoMemory::getMemory(uint32_t index,
|
||||
bool metadata) const
|
||||
{
|
||||
int i;
|
||||
if (index >= mMetaBufCount || (!metadata && index >= mBufferCount))
|
||||
return NULL;
|
||||
|
||||
if (metadata)
|
||||
if (metadata) {
|
||||
#ifdef USE_MEDIA_EXTENSIONS
|
||||
media_metadata_buffer *packet = NULL;
|
||||
|
||||
for (i = 0; i < mMetaBufCount; i++) {
|
||||
packet = (media_metadata_buffer *)mMetadata[i]->data;
|
||||
if (packet != NULL && packet->pHandle == NULL) {
|
||||
packet->pHandle = mNativeHandle[index];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i < mMetaBufCount) {
|
||||
return mMetadata[i];
|
||||
} else {
|
||||
LOGE("No free video meta memory");
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
return mMetadata[index];
|
||||
else
|
||||
#endif
|
||||
} else {
|
||||
return mCameraMemory[index];
|
||||
}
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
* FUNCTION : updateNativeHandle
|
||||
* FUNCTION : getNativeHandle
|
||||
*
|
||||
* DESCRIPTION: Updating native handle pointer
|
||||
* DESCRIPTION: getNativeHandle from video buffer
|
||||
*
|
||||
* PARAMETERS :
|
||||
* @index : buffer index
|
||||
* @metadata: flag if it's metadata
|
||||
*
|
||||
* RETURN : camera native handle ptr
|
||||
* NULL if not supported or failed
|
||||
* RETURN : native_handle_t * type of handle
|
||||
*==========================================================================*/
|
||||
native_handle_t *QCameraVideoMemory::updateNativeHandle(uint32_t index, bool metadata)
|
||||
native_handle_t *QCameraVideoMemory::getNativeHandle(uint32_t index, bool metadata)
|
||||
{
|
||||
if (index >= mMetaBufCount || (!metadata && index >= mBufferCount)) {
|
||||
if (index >= mMetaBufCount || !metadata)
|
||||
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;
|
||||
return mNativeHandle[index];
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
* FUNCTION : closeNativeHandle
|
||||
*
|
||||
* DESCRIPTION: close video native handle
|
||||
* DESCRIPTION: close video native handle and update cached ptrs
|
||||
*
|
||||
* PARAMETERS :
|
||||
* @opaque : ptr to video frame to be returned
|
||||
* @data : ptr to video frame to be returned
|
||||
*
|
||||
* RETURN : int32_t type of status
|
||||
* NO_ERROR -- success
|
||||
|
@ -1601,28 +1615,24 @@ native_handle_t *QCameraVideoMemory::updateNativeHandle(uint32_t index, bool met
|
|||
int QCameraVideoMemory::closeNativeHandle(const void *data, bool metadata)
|
||||
{
|
||||
int32_t rc = NO_ERROR;
|
||||
int32_t index = -1;
|
||||
|
||||
#ifdef USE_MEDIA_EXTENSIONS
|
||||
camera_memory_t *video_mem = NULL;
|
||||
|
||||
if (metadata) {
|
||||
index = getMatchBufIndex(data, metadata);
|
||||
if (index < 0) {
|
||||
LOGE("Invalid buffer");
|
||||
return BAD_VALUE;
|
||||
}
|
||||
video_mem = getMemory(index, metadata);
|
||||
media_metadata_buffer * packet = NULL;
|
||||
if (video_mem) {
|
||||
packet = (media_metadata_buffer *)video_mem->data;
|
||||
}
|
||||
|
||||
if (packet != NULL && packet->eType ==
|
||||
kMetadataBufferTypeNativeHandleSource) {
|
||||
const media_metadata_buffer *packet =
|
||||
(const media_metadata_buffer *)data;
|
||||
if ((packet != NULL) && (packet->eType ==
|
||||
kMetadataBufferTypeNativeHandleSource)
|
||||
&& (packet->pHandle)) {
|
||||
native_handle_close(packet->pHandle);
|
||||
native_handle_delete(packet->pHandle);
|
||||
packet->pHandle = NULL;
|
||||
for (int i = 0; i < mMetaBufCount; i++) {
|
||||
if(mMetadata[i]->data == data) {
|
||||
media_metadata_buffer *mem =
|
||||
(media_metadata_buffer *)mMetadata[i]->data;
|
||||
mem->pHandle = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LOGE("Invalid Data. Could not release");
|
||||
return BAD_VALUE;
|
||||
|
@ -1652,12 +1662,31 @@ int QCameraVideoMemory::getMatchBufIndex(const void *opaque,
|
|||
int index = -1;
|
||||
|
||||
if (metadata) {
|
||||
#ifdef USE_MEDIA_EXTENSIONS
|
||||
const media_metadata_buffer *packet =
|
||||
(const media_metadata_buffer *)opaque;
|
||||
native_handle_t *nh = NULL;
|
||||
if ((packet != NULL) && (packet->eType ==
|
||||
kMetadataBufferTypeNativeHandleSource)
|
||||
&& (packet->pHandle)) {
|
||||
nh = (native_handle_t *)packet->pHandle;
|
||||
int mCommonIdx = (nh->numInts + nh->numFds -
|
||||
VIDEO_METADATA_NUM_COMMON_INTS);
|
||||
for (int i = 0; i < mMetaBufCount; i++) {
|
||||
if(nh->data[mCommonIdx] == mNativeHandle[i]->data[mCommonIdx]) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
for (int i = 0; i < mMetaBufCount; i++) {
|
||||
if (mMetadata[i]->data == opaque) {
|
||||
if(mMetadata[i]->data == opaque) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
for (int i = 0; i < mBufferCount; i++) {
|
||||
if (mCameraMemory[i]->data == opaque) {
|
||||
|
|
|
@ -51,6 +51,8 @@ class QCameraMemoryPool;
|
|||
|
||||
//OFFSET, SIZE, USAGE, TIMESTAMP, FORMAT
|
||||
#define VIDEO_METADATA_NUM_INTS 5
|
||||
//Buffer identity
|
||||
#define VIDEO_METADATA_NUM_COMMON_INTS 1
|
||||
|
||||
enum QCameraMemType {
|
||||
QCAMERA_MEM_TYPE_DEFAULT = 0,
|
||||
|
@ -231,8 +233,8 @@ 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);
|
||||
int closeNativeHandle(const void *data, bool metadata = true);
|
||||
native_handle_t *getNativeHandle(uint32_t index, bool metadata = true);
|
||||
private:
|
||||
camera_memory_t *mMetadata[MM_CAMERA_MAX_NUM_FRAMES];
|
||||
uint8_t mMetaBufCount;
|
||||
|
|
|
@ -1180,13 +1180,27 @@ int32_t QCameraStream::bufDone(const void *opaque, bool isMetaData)
|
|||
{
|
||||
int32_t rc = NO_ERROR;
|
||||
int index = -1;
|
||||
QCameraVideoMemory *mVideoMem = NULL;
|
||||
|
||||
if ((mStreamInfo != NULL)
|
||||
&& (mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH)
|
||||
&& (mStreamBatchBufs != NULL)) {
|
||||
index = mStreamBatchBufs->getMatchBufIndex(opaque, isMetaData);
|
||||
mVideoMem = (QCameraVideoMemory *)mStreamBatchBufs;
|
||||
} else if (mStreamBufs != NULL){
|
||||
index = mStreamBufs->getMatchBufIndex(opaque, isMetaData);
|
||||
mVideoMem = (QCameraVideoMemory *)mStreamBufs;
|
||||
}
|
||||
|
||||
//Close and delete duplicated native handle and FD's.
|
||||
if (mVideoMem != NULL) {
|
||||
rc = mVideoMem->closeNativeHandle(opaque, isMetaData);
|
||||
if (rc != NO_ERROR) {
|
||||
LOGE("Invalid video metadata");
|
||||
return rc;
|
||||
}
|
||||
} else {
|
||||
LOGE("Possible FD leak. Release recording called after stop");
|
||||
}
|
||||
|
||||
if (index == -1 || index >= mNumBufs || mBufDefs == NULL) {
|
||||
|
|
Loading…
Reference in a new issue