Camera3: Remove buffer registration phase
Instead of registering all buffers upfront all client buffers are registered on-the-fly during process capture requests. Bug: 13301331 Change-Id: I6230829f9ac8eb1c7ddc26f2408dc948ce7b4682 Signed-off-by: Daniel Jarai <jaraidaniel@gmail.com>
This commit is contained in:
parent
410f7a39e8
commit
dccf08a6bb
|
@ -42,6 +42,7 @@
|
|||
#include <utils/Errors.h>
|
||||
#include <cutils/properties.h>
|
||||
#include "QCamera3Channel.h"
|
||||
#include <inttypes.h>
|
||||
|
||||
using namespace android;
|
||||
|
||||
|
@ -239,6 +240,8 @@ int32_t QCamera3Channel::start()
|
|||
|
||||
if (m_numStreams > 1) {
|
||||
ALOGE("%s: bundle not supported", __func__);
|
||||
} else if (m_numStreams == 0) {
|
||||
return NO_INIT;
|
||||
}
|
||||
|
||||
for (int i = 0; i < m_numStreams; i++) {
|
||||
|
@ -433,6 +436,7 @@ void QCamera3Channel::streamCbRoutine(mm_camera_super_buf_t *super_frame,
|
|||
* @cam_ops : ptr to camera ops table
|
||||
* @cb_routine : callback routine to frame aggregator
|
||||
* @stream : camera3_stream_t structure
|
||||
* @stream_type: Channel stream type
|
||||
*
|
||||
* RETURN : none
|
||||
*==========================================================================*/
|
||||
|
@ -441,15 +445,16 @@ QCamera3RegularChannel::QCamera3RegularChannel(uint32_t cam_handle,
|
|||
channel_cb_routine cb_routine,
|
||||
cam_padding_info_t *paddingInfo,
|
||||
void *userData,
|
||||
camera3_stream_t *stream) :
|
||||
camera3_stream_t *stream,
|
||||
cam_stream_type_t stream_type) :
|
||||
QCamera3Channel(cam_handle, cam_ops, cb_routine,
|
||||
paddingInfo, userData),
|
||||
mCamera3Stream(stream),
|
||||
mNumBufs(0),
|
||||
mRegisteredBuffers(0),
|
||||
mCamera3Buffers(NULL),
|
||||
mMemory(NULL),
|
||||
mWidth(stream->width),
|
||||
mHeight(stream->height)
|
||||
mStreamType(stream_type)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -472,15 +477,15 @@ QCamera3RegularChannel::QCamera3RegularChannel(uint32_t cam_handle,
|
|||
cam_padding_info_t *paddingInfo,
|
||||
void *userData,
|
||||
camera3_stream_t *stream,
|
||||
uint32_t width, uint32_t height) :
|
||||
uint32_t width __unused, uint32_t height __unused) :
|
||||
QCamera3Channel(cam_handle, cam_ops, cb_routine,
|
||||
paddingInfo, userData),
|
||||
mCamera3Stream(stream),
|
||||
mNumBufs(0),
|
||||
mRegisteredBuffers(0),
|
||||
mCamera3Buffers(NULL),
|
||||
mMemory(NULL),
|
||||
mWidth(width),
|
||||
mHeight(height)
|
||||
mStreamType(CAM_STREAM_TYPE_PREVIEW /*stream_type*/)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -500,10 +505,102 @@ QCamera3RegularChannel::~QCamera3RegularChannel()
|
|||
}
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
* FUNCTION : initialize
|
||||
*
|
||||
* DESCRIPTION: Initialize and add camera channel & stream
|
||||
*
|
||||
* PARAMETERS :
|
||||
*
|
||||
* RETURN : int32_t type of status
|
||||
* NO_ERROR -- success
|
||||
* none-zero failure code
|
||||
*==========================================================================*/
|
||||
|
||||
int32_t QCamera3RegularChannel::initialize()
|
||||
{
|
||||
//TO DO
|
||||
return 0;
|
||||
int32_t rc = NO_ERROR;
|
||||
cam_format_t streamFormat;
|
||||
cam_dimension_t streamDim;
|
||||
|
||||
if (NULL == mCamera3Stream) {
|
||||
ALOGE("%s: Camera stream uninitialized", __func__);
|
||||
return NO_INIT;
|
||||
}
|
||||
|
||||
if (1 <= m_numStreams) {
|
||||
// Only one stream per channel supported in v3 Hal
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
rc = init(NULL, NULL);
|
||||
if (rc < 0) {
|
||||
ALOGE("%s: init failed", __func__);
|
||||
return rc;
|
||||
}
|
||||
|
||||
mNumBufs = CAM_MAX_NUM_BUFS_PER_STREAM;
|
||||
mCamera3Buffers = new buffer_handle_t*[mNumBufs];
|
||||
if (mCamera3Buffers == NULL) {
|
||||
ALOGE("%s: Failed to allocate buffer_handle_t*", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (mCamera3Stream->format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
|
||||
if (mStreamType == CAM_STREAM_TYPE_VIDEO) {
|
||||
streamFormat = CAM_FORMAT_YUV_420_NV12;
|
||||
} else if (mStreamType == CAM_STREAM_TYPE_PREVIEW) {
|
||||
streamFormat = CAM_FORMAT_YUV_420_NV21;
|
||||
} else {
|
||||
//TODO: Add a new flag in libgralloc for ZSL buffers, and its size needs
|
||||
// to be properly aligned and padded.
|
||||
streamFormat = CAM_FORMAT_YUV_420_NV21;
|
||||
}
|
||||
} else if(mCamera3Stream->format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
|
||||
streamFormat = CAM_FORMAT_YUV_420_NV21;
|
||||
} else if (mCamera3Stream->format == HAL_PIXEL_FORMAT_RAW_OPAQUE ||
|
||||
mCamera3Stream->format == HAL_PIXEL_FORMAT_RAW16) {
|
||||
// Bayer pattern doesn't matter here.
|
||||
// All CAMIF raw format uses 10bit.
|
||||
streamFormat = CAM_FORMAT_BAYER_QCOM_RAW_10BPP_GBRG;
|
||||
} else {
|
||||
|
||||
//TODO: Fail for other types of streams for now
|
||||
ALOGE("%s: format is not IMPLEMENTATION_DEFINED or flexible", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
streamDim.width = mCamera3Stream->width;
|
||||
streamDim.height = mCamera3Stream->height;
|
||||
|
||||
rc = QCamera3Channel::addStream(mStreamType,
|
||||
streamFormat,
|
||||
streamDim,
|
||||
mNumBufs);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
* FUNCTION : start
|
||||
*
|
||||
* DESCRIPTION: start a regular channel
|
||||
*
|
||||
* PARAMETERS :
|
||||
*
|
||||
* RETURN : int32_t type of status
|
||||
* NO_ERROR -- success
|
||||
* none-zero failure code
|
||||
*==========================================================================*/
|
||||
int32_t QCamera3RegularChannel::start()
|
||||
{
|
||||
int32_t rc = NO_ERROR;
|
||||
|
||||
if (0 < mRegisteredBuffers) {
|
||||
rc = QCamera3Channel::start();
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
|
@ -524,11 +621,22 @@ int32_t QCamera3RegularChannel::request(buffer_handle_t *buffer, uint32_t frameN
|
|||
|
||||
int32_t rc = NO_ERROR;
|
||||
int index;
|
||||
|
||||
if (NULL == buffer) {
|
||||
ALOGE("%s: Invalid buffer in channel request", __func__);
|
||||
return BAD_VALUE;
|
||||
}
|
||||
|
||||
if(!m_bIsActive) {
|
||||
ALOGD("%s: First request on this channel starting stream",__func__);
|
||||
start();
|
||||
if(rc != NO_ERROR) {
|
||||
ALOGE("%s: Failed to start the stream on the request",__func__);
|
||||
rc = registerBuffer(buffer);
|
||||
if (NO_ERROR != rc) {
|
||||
ALOGE("%s: On-the-fly buffer registration failed %d",
|
||||
__func__, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = start();
|
||||
if (NO_ERROR != rc) {
|
||||
return rc;
|
||||
}
|
||||
} else {
|
||||
|
@ -542,8 +650,19 @@ int32_t QCamera3RegularChannel::request(buffer_handle_t *buffer, uint32_t frameN
|
|||
|
||||
index = mMemory->getMatchBufIndex((void*)buffer);
|
||||
if(index < 0) {
|
||||
ALOGE("%s: Could not find object among registered buffers",__func__);
|
||||
return DEAD_OBJECT;
|
||||
rc = registerBuffer(buffer);
|
||||
if (NO_ERROR != rc) {
|
||||
ALOGE("%s: On-the-fly buffer registration failed %d",
|
||||
__func__, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
index = mMemory->getMatchBufIndex((void*)buffer);
|
||||
if (index < 0) {
|
||||
ALOGE("%s: Could not find object among registered buffers",
|
||||
__func__);
|
||||
return DEAD_OBJECT;
|
||||
}
|
||||
}
|
||||
|
||||
rc = mStreams[0]->bufDone(index);
|
||||
|
@ -557,72 +676,54 @@ int32_t QCamera3RegularChannel::request(buffer_handle_t *buffer, uint32_t frameN
|
|||
}
|
||||
|
||||
/*===========================================================================
|
||||
* FUNCTION : registerBuffers
|
||||
* FUNCTION : registerBuffer
|
||||
*
|
||||
* DESCRIPTION: register streaming buffers to the channel object
|
||||
* DESCRIPTION: register streaming buffer to the channel object
|
||||
*
|
||||
* PARAMETERS :
|
||||
* @num_buffers : number of buffers to be registered
|
||||
* @buffers : buffer to be registered
|
||||
* @buffer : buffer to be registered
|
||||
*
|
||||
* RETURN : 0 on a success start of capture
|
||||
* -EINVAL on invalid input
|
||||
* -ENOMEM on failure to register the buffer
|
||||
* -ENODEV on serious error
|
||||
* RETURN : int32_t type of status
|
||||
* NO_ERROR -- success
|
||||
* none-zero failure code
|
||||
*==========================================================================*/
|
||||
int32_t QCamera3RegularChannel::registerBuffers(uint32_t num_buffers, buffer_handle_t **buffers)
|
||||
int32_t QCamera3RegularChannel::registerBuffer(buffer_handle_t *buffer)
|
||||
{
|
||||
int rc = 0;
|
||||
struct private_handle_t *priv_handle = (struct private_handle_t *)(*buffers[0]);
|
||||
cam_stream_type_t streamType;
|
||||
cam_format_t streamFormat;
|
||||
cam_dimension_t streamDim;
|
||||
|
||||
rc = init(NULL, NULL);
|
||||
if (rc < 0) {
|
||||
ALOGE("%s: init failed", __func__);
|
||||
if (mRegisteredBuffers > (mNumBufs - 1)) {
|
||||
ALOGE("%s: Trying to register more buffers than initially requested",
|
||||
__func__);
|
||||
return BAD_VALUE;
|
||||
}
|
||||
|
||||
if (0 == m_numStreams) {
|
||||
rc = initialize();
|
||||
if (rc != NO_ERROR) {
|
||||
ALOGE("%s: Couldn't initialize camera stream %d",
|
||||
__func__, rc);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
if(NULL == mMemory) {
|
||||
mMemory = new QCamera3GrallocMemory();
|
||||
if (mMemory == NULL) {
|
||||
return NO_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
rc = mMemory->registerBuffer(buffer);
|
||||
if (ALREADY_EXISTS == rc) {
|
||||
return NO_ERROR;
|
||||
} else if (NO_ERROR != rc) {
|
||||
ALOGE("%s: Buffer %p couldn't be registered %d", __func__, buffer, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (mCamera3Stream->format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
|
||||
if (priv_handle->flags & private_handle_t::PRIV_FLAGS_VIDEO_ENCODER) {
|
||||
streamType = CAM_STREAM_TYPE_VIDEO;
|
||||
streamFormat = CAM_FORMAT_YUV_420_NV12;
|
||||
} else if (priv_handle->flags & private_handle_t::PRIV_FLAGS_HW_TEXTURE) {
|
||||
streamType = CAM_STREAM_TYPE_PREVIEW;
|
||||
streamFormat = CAM_FORMAT_YUV_420_NV21;
|
||||
} else {
|
||||
//TODO: Add a new flag in libgralloc for ZSL buffers, and its size needs
|
||||
// to be properly aligned and padded.
|
||||
ALOGE("%s: priv_handle->flags 0x%x not supported",
|
||||
__func__, priv_handle->flags);
|
||||
streamType = CAM_STREAM_TYPE_SNAPSHOT;
|
||||
streamFormat = CAM_FORMAT_YUV_420_NV21;
|
||||
}
|
||||
} else if(mCamera3Stream->format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
|
||||
streamType = CAM_STREAM_TYPE_CALLBACK;
|
||||
streamFormat = CAM_FORMAT_YUV_420_NV21;
|
||||
} else {
|
||||
//TODO: Fail for other types of streams for now
|
||||
ALOGE("%s: format is not IMPLEMENTATION_DEFINED or flexible", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
mCamera3Buffers[mRegisteredBuffers] = buffer;
|
||||
mRegisteredBuffers++;
|
||||
|
||||
/* Bookkeep buffer set because they go out of scope after register call */
|
||||
mNumBufs = num_buffers;
|
||||
mCamera3Buffers = new buffer_handle_t*[num_buffers];
|
||||
if (mCamera3Buffers == NULL) {
|
||||
ALOGE("%s: Failed to allocate buffer_handle_t*", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
for (size_t i = 0; i < num_buffers; i++)
|
||||
mCamera3Buffers[i] = buffers[i];
|
||||
|
||||
streamDim.width = mWidth;
|
||||
streamDim.height = mHeight;
|
||||
|
||||
rc = QCamera3Channel::addStream(streamType, streamFormat, streamDim,
|
||||
num_buffers);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -677,29 +778,23 @@ void QCamera3RegularChannel::streamCbRoutine(
|
|||
|
||||
QCamera3Memory* QCamera3RegularChannel::getStreamBufs(uint32_t /*len*/)
|
||||
{
|
||||
if (mNumBufs == 0 || mCamera3Buffers == NULL) {
|
||||
ALOGE("%s: buffers not registered yet", __func__);
|
||||
return NULL;
|
||||
if(NULL == mMemory) {
|
||||
mMemory = new QCamera3GrallocMemory();
|
||||
if (mMemory == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
mMemory = new QCamera3GrallocMemory();
|
||||
if (mMemory == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (mMemory->registerBuffers(mNumBufs, mCamera3Buffers) < 0) {
|
||||
delete mMemory;
|
||||
mMemory = NULL;
|
||||
return NULL;
|
||||
}
|
||||
return mMemory;
|
||||
}
|
||||
|
||||
void QCamera3RegularChannel::putStreamBufs()
|
||||
{
|
||||
mMemory->unregisterBuffers();
|
||||
delete mMemory;
|
||||
mMemory = NULL;
|
||||
if (NULL != mMemory) {
|
||||
mMemory->unregisterBuffers();
|
||||
delete mMemory;
|
||||
mMemory = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int QCamera3RegularChannel::kMaxBuffers = 7;
|
||||
|
@ -763,13 +858,6 @@ int32_t QCamera3MetadataChannel::request(buffer_handle_t * /*buffer*/,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t QCamera3MetadataChannel::registerBuffers(uint32_t /*num_buffers*/,
|
||||
buffer_handle_t ** /*buffers*/)
|
||||
{
|
||||
// no registerBuffers are supported for metadata channel
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
void QCamera3MetadataChannel::streamCbRoutine(
|
||||
mm_camera_super_buf_t *super_frame,
|
||||
QCamera3Stream * /*stream*/)
|
||||
|
@ -923,6 +1011,7 @@ QCamera3PicChannel::QCamera3PicChannel(uint32_t cam_handle,
|
|||
mCamera3Buffers(NULL),
|
||||
mJpegSettings(NULL),
|
||||
mCurrentBufIndex(-1),
|
||||
mRegisteredBuffers(0),
|
||||
mMemory(NULL),
|
||||
mYuvMemory(NULL),
|
||||
mMetaFrame(NULL)
|
||||
|
@ -956,6 +1045,16 @@ int32_t QCamera3PicChannel::initialize()
|
|||
cam_format_t streamFormat;
|
||||
mm_camera_channel_attr_t attr;
|
||||
|
||||
if (NULL == mCamera3Stream) {
|
||||
ALOGE("%s: Camera stream uninitialized", __func__);
|
||||
return NO_INIT;
|
||||
}
|
||||
|
||||
if (1 <= m_numStreams) {
|
||||
// Only one stream per channel supported in v3 Hal
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
|
||||
attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
|
||||
attr.look_back = 1;
|
||||
|
@ -976,6 +1075,13 @@ int32_t QCamera3PicChannel::initialize()
|
|||
|
||||
int num_buffers = 1;
|
||||
|
||||
mNumBufs = CAM_MAX_NUM_BUFS_PER_STREAM;
|
||||
mCamera3Buffers = new buffer_handle_t*[num_buffers];
|
||||
if (mCamera3Buffers == NULL) {
|
||||
ALOGE("%s: Failed to allocate buffer_handle_t*", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rc = QCamera3Channel::addStream(streamType, streamFormat, streamDim,
|
||||
num_buffers);
|
||||
|
||||
|
@ -1010,18 +1116,13 @@ int32_t QCamera3PicChannel::request(buffer_handle_t *buffer,
|
|||
|
||||
|
||||
if(!mMemory) {
|
||||
ALOGE("%s: 1", __func__);
|
||||
if(pInputBuffer) {
|
||||
ALOGE("%s: 2", __func__);
|
||||
mMemory = new QCamera3GrallocMemory();
|
||||
if (mMemory == NULL) {
|
||||
return NO_MEMORY;
|
||||
}
|
||||
|
||||
//Registering Jpeg output buffer
|
||||
if (mMemory->registerBuffers(mNumBufs, mCamera3Buffers) < 0) {
|
||||
delete mMemory;
|
||||
mMemory = NULL;
|
||||
return NO_MEMORY;
|
||||
}
|
||||
} else {
|
||||
ALOGE("%s: error, Gralloc Memory object not yet created for this stream",__func__);
|
||||
return NO_MEMORY;
|
||||
|
@ -1030,8 +1131,18 @@ int32_t QCamera3PicChannel::request(buffer_handle_t *buffer,
|
|||
|
||||
index = mMemory->getMatchBufIndex((void*)buffer);
|
||||
if(index < 0) {
|
||||
ALOGE("%s: Could not find object among registered buffers",__func__);
|
||||
return DEAD_OBJECT;
|
||||
rc = registerBuffer(buffer);
|
||||
if (NO_ERROR != rc) {
|
||||
ALOGE("%s: On-the-fly buffer registration failed %d",
|
||||
__func__, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
index = mMemory->getMatchBufIndex((void*)buffer);
|
||||
if (index < 0) {
|
||||
ALOGE("%s: Could not find object among registered buffers",__func__);
|
||||
return DEAD_OBJECT;
|
||||
}
|
||||
}
|
||||
rc = mMemory->markFrameNumber(index, frameNumber);
|
||||
|
||||
|
@ -1090,40 +1201,55 @@ void QCamera3PicChannel::dataNotifyCB(mm_camera_super_buf_t *recvd_frame,
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
int32_t QCamera3PicChannel::registerBuffers(uint32_t num_buffers,
|
||||
buffer_handle_t **buffers)
|
||||
/*===========================================================================
|
||||
* FUNCTION : registerBuffer
|
||||
*
|
||||
* DESCRIPTION: register streaming buffer to the channel object
|
||||
*
|
||||
* PARAMETERS :
|
||||
* @buffer : buffer to be registered
|
||||
*
|
||||
* RETURN : int32_t type of status
|
||||
* NO_ERROR -- success
|
||||
* none-zero failure code
|
||||
*==========================================================================*/
|
||||
int32_t QCamera3PicChannel::registerBuffer(buffer_handle_t *buffer)
|
||||
{
|
||||
int rc = 0;
|
||||
cam_stream_type_t streamType;
|
||||
cam_format_t streamFormat;
|
||||
|
||||
ALOGV("%s: E",__func__);
|
||||
rc = QCamera3PicChannel::initialize();
|
||||
if (rc < 0) {
|
||||
ALOGE("%s: init failed", __func__);
|
||||
if (mRegisteredBuffers > (mNumBufs - 1)) {
|
||||
ALOGE("%s: Trying to register more buffers than initially requested",
|
||||
__func__);
|
||||
return BAD_VALUE;
|
||||
}
|
||||
|
||||
if (0 == m_numStreams) {
|
||||
rc = initialize();
|
||||
if (rc != NO_ERROR) {
|
||||
ALOGE("%s: Couldn't initialize camera stream %d",
|
||||
__func__, rc);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
if(NULL == mMemory) {
|
||||
mMemory = new QCamera3GrallocMemory();
|
||||
if (mMemory == NULL) {
|
||||
return NO_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
rc = mMemory->registerBuffer(buffer);
|
||||
if (ALREADY_EXISTS == rc) {
|
||||
return NO_ERROR;
|
||||
} else if (NO_ERROR != rc) {
|
||||
ALOGE("%s: Buffer %p couldn't be registered %d", __func__, buffer, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (mCamera3Stream->format == HAL_PIXEL_FORMAT_BLOB) {
|
||||
streamType = CAM_STREAM_TYPE_NON_ZSL_SNAPSHOT;
|
||||
streamFormat = CAM_FORMAT_YUV_420_NV21;
|
||||
} else {
|
||||
//TODO: Fail for other types of streams for now
|
||||
ALOGE("%s: format is not BLOB", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
/* Bookkeep buffer set because they go out of scope after register call */
|
||||
mNumBufs = num_buffers;
|
||||
mCamera3Buffers = new buffer_handle_t*[num_buffers];
|
||||
if (mCamera3Buffers == NULL) {
|
||||
ALOGE("%s: Failed to allocate buffer_handle_t*", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
for (size_t i = 0; i < num_buffers; i++)
|
||||
mCamera3Buffers[i] = buffers[i];
|
||||
mCamera3Buffers[mRegisteredBuffers] = buffer;
|
||||
mRegisteredBuffers++;
|
||||
|
||||
ALOGV("%s: X",__func__);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -1186,20 +1312,11 @@ QCamera3Memory* QCamera3PicChannel::getStreamBufs(uint32_t len)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if(mMemory) {
|
||||
delete mMemory;
|
||||
mMemory = NULL;
|
||||
}
|
||||
mMemory = new QCamera3GrallocMemory();
|
||||
if (mMemory == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//Registering Jpeg output buffer
|
||||
if (mMemory->registerBuffers(mNumBufs, mCamera3Buffers) < 0) {
|
||||
delete mMemory;
|
||||
mMemory = NULL;
|
||||
return NULL;
|
||||
if(NULL == mMemory) {
|
||||
mMemory = new QCamera3GrallocMemory();
|
||||
if (mMemory == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
mYuvMemory = new QCamera3HeapMemory();
|
||||
|
@ -1221,9 +1338,11 @@ QCamera3Memory* QCamera3PicChannel::getStreamBufs(uint32_t len)
|
|||
|
||||
void QCamera3PicChannel::putStreamBufs()
|
||||
{
|
||||
mMemory->unregisterBuffers();
|
||||
delete mMemory;
|
||||
mMemory = NULL;
|
||||
if (NULL != mMemory) {
|
||||
mMemory->unregisterBuffers();
|
||||
delete mMemory;
|
||||
mMemory = NULL;
|
||||
}
|
||||
|
||||
mYuvMemory->deallocate();
|
||||
delete mYuvMemory;
|
||||
|
@ -1969,21 +2088,6 @@ QCamera3ReprocessChannel::QCamera3ReprocessChannel() :
|
|||
{
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
* FUNCTION : QCamera3ReprocessChannel
|
||||
*
|
||||
* DESCRIPTION: register the buffers of the reprocess channel
|
||||
*
|
||||
* PARAMETERS : none
|
||||
*
|
||||
* RETURN : none
|
||||
*==========================================================================*/
|
||||
int32_t QCamera3ReprocessChannel::registerBuffers(
|
||||
uint32_t /*num_buffers*/, buffer_handle_t ** /*buffers*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
* FUNCTION : getStreamBufs
|
||||
*
|
||||
|
|
|
@ -64,14 +64,12 @@ public:
|
|||
cam_format_t streamFormat,
|
||||
cam_dimension_t streamDim,
|
||||
uint8_t minStreamBufnum);
|
||||
int32_t start();
|
||||
virtual int32_t start();
|
||||
int32_t stop();
|
||||
int32_t bufDone(mm_camera_super_buf_t *recvd_frame);
|
||||
|
||||
uint32_t getStreamTypeMask();
|
||||
|
||||
virtual int32_t registerBuffers(uint32_t num_buffers,
|
||||
buffer_handle_t **buffers) = 0;
|
||||
virtual int32_t initialize() = 0;
|
||||
virtual int32_t request(buffer_handle_t * /*buffer*/,
|
||||
uint32_t /*frameNumber*/){ return 0;};
|
||||
|
@ -83,6 +81,7 @@ public:
|
|||
virtual void streamCbRoutine(mm_camera_super_buf_t *super_frame,
|
||||
QCamera3Stream *stream) = 0;
|
||||
|
||||
virtual int32_t registerBuffer(buffer_handle_t *buffer) = 0;
|
||||
virtual QCamera3Memory *getStreamBufs(uint32_t len) = 0;
|
||||
virtual void putStreamBufs() = 0;
|
||||
|
||||
|
@ -129,7 +128,8 @@ public:
|
|||
channel_cb_routine cb_routine,
|
||||
cam_padding_info_t *paddingInfo,
|
||||
void *userData,
|
||||
camera3_stream_t *stream);
|
||||
camera3_stream_t *stream,
|
||||
cam_stream_type_t stream_type);
|
||||
QCamera3RegularChannel(uint32_t cam_handle,
|
||||
mm_camera_ops_t *cam_ops,
|
||||
channel_cb_routine cb_routine,
|
||||
|
@ -139,30 +139,28 @@ public:
|
|||
uint32_t width, uint32_t height);
|
||||
virtual ~QCamera3RegularChannel();
|
||||
|
||||
virtual int32_t start();
|
||||
virtual int32_t initialize();
|
||||
virtual int32_t request(buffer_handle_t *buffer, uint32_t frameNumber);
|
||||
virtual int32_t registerBuffers(uint32_t num_buffers,
|
||||
buffer_handle_t **buffers);
|
||||
virtual void streamCbRoutine(mm_camera_super_buf_t *super_frame,
|
||||
QCamera3Stream *stream);
|
||||
|
||||
virtual QCamera3Memory *getStreamBufs(uint32_t le);
|
||||
virtual void putStreamBufs();
|
||||
mm_camera_buf_def_t* getInternalFormatBuffer(buffer_handle_t* buffer);
|
||||
virtual int32_t registerBuffer(buffer_handle_t *buffer);
|
||||
|
||||
public:
|
||||
static int kMaxBuffers;
|
||||
private:
|
||||
camera3_stream_t *mCamera3Stream;
|
||||
uint32_t mNumBufs;
|
||||
uint32_t mRegisteredBuffers;
|
||||
buffer_handle_t **mCamera3Buffers;
|
||||
|
||||
QCamera3GrallocMemory *mMemory;
|
||||
// width and height of internal stream may be different than what's
|
||||
// specified in camera3_stream_t. For example: ZSL stream size is
|
||||
// always the active region size, but internally we use the JPEG
|
||||
// size.
|
||||
uint32_t mWidth, mHeight;
|
||||
|
||||
cam_stream_type_t mStreamType; // Stream type
|
||||
};
|
||||
|
||||
/* QCamera3MetadataChannel is for metadata stream generated by camera daemon. */
|
||||
|
@ -179,18 +177,48 @@ public:
|
|||
virtual int32_t initialize();
|
||||
|
||||
virtual int32_t request(buffer_handle_t *buffer, uint32_t frameNumber);
|
||||
virtual int32_t registerBuffers(uint32_t num_buffers,
|
||||
buffer_handle_t **buffers);
|
||||
virtual void streamCbRoutine(mm_camera_super_buf_t *super_frame,
|
||||
QCamera3Stream *stream);
|
||||
|
||||
virtual QCamera3Memory *getStreamBufs(uint32_t le);
|
||||
virtual void putStreamBufs();
|
||||
virtual int32_t registerBuffer(buffer_handle_t * /*buffer*/)
|
||||
{ return NO_ERROR; };
|
||||
|
||||
private:
|
||||
QCamera3HeapMemory *mMemory;
|
||||
};
|
||||
|
||||
/* QCameraRawChannel is for Dumping raw stream generated by camera daemon. */
|
||||
class QCameraRawChannel : public QCamera3Channel
|
||||
{
|
||||
public:
|
||||
QCameraRawChannel(uint32_t cam_handle,
|
||||
mm_camera_ops_t *cam_ops,
|
||||
channel_cb_routine cb_routine,
|
||||
cam_padding_info_t *paddingInfo,
|
||||
void *userData,
|
||||
cam_dimension_t *raw_dim);
|
||||
virtual ~QCameraRawChannel();
|
||||
|
||||
virtual int32_t initialize();
|
||||
|
||||
virtual int32_t request(buffer_handle_t *buffer, uint32_t frameNumber);
|
||||
virtual void streamCbRoutine(mm_camera_super_buf_t *super_frame,
|
||||
QCamera3Stream *stream);
|
||||
|
||||
virtual QCamera3Memory *getStreamBufs(uint32_t le);
|
||||
virtual void putStreamBufs();
|
||||
void dumpRawSnapshot(mm_camera_buf_def_t *frame);
|
||||
virtual int32_t registerBuffer(buffer_handle_t * /*buffer*/)
|
||||
{ return NO_ERROR; };
|
||||
|
||||
private:
|
||||
QCamera3HeapMemory *mMemory;
|
||||
uint32_t mWidth, mHeight;
|
||||
uint32_t mMaxBuffers;
|
||||
};
|
||||
|
||||
/* QCamera3PicChannel is for JPEG stream, which contains a YUV stream generated
|
||||
* by the hardware, and encoded to a JPEG stream */
|
||||
class QCamera3PicChannel : public QCamera3Channel
|
||||
|
@ -209,8 +237,6 @@ public:
|
|||
virtual int32_t request(buffer_handle_t *buffer,
|
||||
uint32_t frameNumber, jpeg_settings_t* mJpegSettings,
|
||||
mm_camera_buf_def_t* pInputBuffer,QCamera3Channel* pInputChannel);
|
||||
virtual int32_t registerBuffers(uint32_t num_buffers,
|
||||
buffer_handle_t **buffers);
|
||||
virtual void streamCbRoutine(mm_camera_super_buf_t *super_frame,
|
||||
QCamera3Stream *stream);
|
||||
|
||||
|
@ -233,6 +259,7 @@ public:
|
|||
void queueMetadata(mm_camera_super_buf_t *metadata_buf,
|
||||
QCamera3Channel *pMetaChannel,
|
||||
bool relinquish);
|
||||
virtual int32_t registerBuffer(buffer_handle_t *buffer);
|
||||
|
||||
public:
|
||||
static int kMaxBuffers;
|
||||
|
@ -244,7 +271,7 @@ private:
|
|||
jpeg_settings_t* mJpegSettings;
|
||||
int32_t mCurrentBufIndex;
|
||||
bool m_bWNROn;
|
||||
|
||||
uint32_t mRegisteredBuffers;
|
||||
|
||||
QCamera3GrallocMemory *mMemory;
|
||||
QCamera3HeapMemory *mYuvMemory;
|
||||
|
@ -269,7 +296,6 @@ public:
|
|||
// offline reprocess
|
||||
int32_t doReprocess(int buf_fd, uint32_t buf_length, int32_t &ret_val,
|
||||
mm_camera_super_buf_t *meta_buf);
|
||||
virtual int32_t registerBuffers(uint32_t num_buffers, buffer_handle_t **buffers);
|
||||
virtual QCamera3Memory *getStreamBufs(uint32_t len);
|
||||
virtual void putStreamBufs();
|
||||
virtual int32_t initialize();
|
||||
|
@ -282,6 +308,9 @@ public:
|
|||
QCamera3Channel *pMetaChannel);
|
||||
QCamera3Stream *getStreamBySourceHandle(uint32_t srcHandle);
|
||||
int32_t metadataBufDone(mm_camera_super_buf_t *recvd_frame);
|
||||
virtual int32_t registerBuffer(buffer_handle_t * /*buffer*/)
|
||||
{ return NO_ERROR; };
|
||||
|
||||
public:
|
||||
void *picChHandle;
|
||||
private:
|
||||
|
|
|
@ -43,7 +43,6 @@ class QCamera3Channel;
|
|||
typedef enum {
|
||||
INVALID,
|
||||
VALID,
|
||||
RECONFIGURE,
|
||||
} stream_status_t;
|
||||
|
||||
typedef struct {
|
||||
|
@ -81,4 +80,5 @@ class QCamera3Channel;
|
|||
|
||||
};//namespace qcamera
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -235,9 +235,6 @@ QCamera3HardwareInterface::~QCamera3HardwareInterface()
|
|||
for (List<stream_info_t *>::iterator it = mStreamInfo.begin();
|
||||
it != mStreamInfo.end(); it++) {
|
||||
QCamera3Channel *channel = (*it)->channel;
|
||||
if ((*it)->registered && (*it)->buffer_set.buffers) {
|
||||
delete[] (buffer_handle_t*)(*it)->buffer_set.buffers;
|
||||
}
|
||||
if (channel)
|
||||
delete channel;
|
||||
free (*it);
|
||||
|
@ -484,10 +481,8 @@ int QCamera3HardwareInterface::configureStreams(
|
|||
QCamera3Channel *channel =
|
||||
(QCamera3Channel*)(*it)->stream->priv;
|
||||
stream_exists = true;
|
||||
(*it)->status = RECONFIGURE;
|
||||
/*delete the channel object associated with the stream because
|
||||
we need to reconfigure*/
|
||||
delete channel;
|
||||
(*it)->status = VALID;
|
||||
(*it)->stream->priv = NULL;
|
||||
(*it)->channel = NULL;
|
||||
}
|
||||
|
@ -498,7 +493,6 @@ int QCamera3HardwareInterface::configureStreams(
|
|||
stream_info = (stream_info_t* )malloc(sizeof(stream_info_t));
|
||||
stream_info->stream = newStream;
|
||||
stream_info->status = VALID;
|
||||
stream_info->registered = 0;
|
||||
stream_info->channel = NULL;
|
||||
mStreamInfo.push_back(stream_info);
|
||||
}
|
||||
|
@ -523,7 +517,6 @@ int QCamera3HardwareInterface::configureStreams(
|
|||
if(((*it)->status) == INVALID){
|
||||
QCamera3Channel *channel = (QCamera3Channel*)(*it)->stream->priv;
|
||||
delete channel;
|
||||
delete[] (buffer_handle_t*)(*it)->buffer_set.buffers;
|
||||
free(*it);
|
||||
it = mStreamInfo.erase(it);
|
||||
} else {
|
||||
|
@ -558,6 +551,33 @@ int QCamera3HardwareInterface::configureStreams(
|
|||
/* Allocate channel objects for the requested streams */
|
||||
for (size_t i = 0; i < streamList->num_streams; i++) {
|
||||
camera3_stream_t *newStream = streamList->streams[i];
|
||||
uint32_t stream_usage = newStream->usage;
|
||||
cam_stream_type_t stream_type;
|
||||
if (newStream->stream_type == CAMERA3_STREAM_BIDIRECTIONAL &&
|
||||
newStream->format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED && jpegStream){
|
||||
stream_type = CAM_STREAM_TYPE_SNAPSHOT;
|
||||
} else {
|
||||
switch (newStream->format) {
|
||||
case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED :
|
||||
{
|
||||
if (stream_usage & private_handle_t::PRIV_FLAGS_VIDEO_ENCODER) {
|
||||
stream_type = CAM_STREAM_TYPE_VIDEO;
|
||||
} else {
|
||||
stream_type = CAM_STREAM_TYPE_PREVIEW;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case HAL_PIXEL_FORMAT_YCbCr_420_888:
|
||||
stream_type = CAM_STREAM_TYPE_CALLBACK;
|
||||
break;
|
||||
case HAL_PIXEL_FORMAT_BLOB:
|
||||
stream_type = CAM_STREAM_TYPE_NON_ZSL_SNAPSHOT;
|
||||
break;
|
||||
default:
|
||||
stream_type = CAM_STREAM_TYPE_DEFAULT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (newStream->priv == NULL) {
|
||||
//New stream, construct channel
|
||||
switch (newStream->stream_type) {
|
||||
|
@ -586,24 +606,21 @@ int QCamera3HardwareInterface::configureStreams(
|
|||
|
||||
if (newStream->stream_type == CAMERA3_STREAM_OUTPUT ||
|
||||
newStream->stream_type == CAMERA3_STREAM_BIDIRECTIONAL) {
|
||||
QCamera3Channel *channel;
|
||||
QCamera3Channel *channel = NULL;
|
||||
switch (newStream->format) {
|
||||
case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
|
||||
case HAL_PIXEL_FORMAT_YCbCr_420_888:
|
||||
newStream->max_buffers = QCamera3RegularChannel::kMaxBuffers;
|
||||
if (newStream->stream_type == CAMERA3_STREAM_BIDIRECTIONAL &&
|
||||
jpegStream) {
|
||||
uint32_t width = jpegStream->width;
|
||||
uint32_t height = jpegStream->height;
|
||||
mIsZslMode = true;
|
||||
channel = new QCamera3RegularChannel(mCameraHandle->camera_handle,
|
||||
mCameraHandle->ops, captureResultCb,
|
||||
&gCamCapability[mCameraId]->padding_info, this, newStream,
|
||||
width, height);
|
||||
} else
|
||||
channel = new QCamera3RegularChannel(mCameraHandle->camera_handle,
|
||||
mCameraHandle->ops, captureResultCb,
|
||||
&gCamCapability[mCameraId]->padding_info, this, newStream);
|
||||
}
|
||||
channel = new QCamera3RegularChannel(mCameraHandle->camera_handle,
|
||||
mCameraHandle->ops, captureResultCb,
|
||||
&gCamCapability[mCameraId]->padding_info,
|
||||
this,
|
||||
newStream,
|
||||
(cam_stream_type_t) stream_type);
|
||||
if (channel == NULL) {
|
||||
ALOGE("%s: allocation of channel failed", __func__);
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
|
@ -645,27 +662,6 @@ int QCamera3HardwareInterface::configureStreams(
|
|||
}
|
||||
}
|
||||
|
||||
/*For the streams to be reconfigured we need to register the buffers
|
||||
since the framework wont*/
|
||||
for (List<stream_info_t *>::iterator it = mStreamInfo.begin();
|
||||
it != mStreamInfo.end(); it++) {
|
||||
if ((*it)->status == RECONFIGURE) {
|
||||
QCamera3Channel *channel = (QCamera3Channel *)(*it)->stream->priv;
|
||||
/*only register buffers for streams that have already been
|
||||
registered*/
|
||||
if ((*it)->registered) {
|
||||
rc = channel->registerBuffers((*it)->buffer_set.num_buffers,
|
||||
(*it)->buffer_set.buffers);
|
||||
if (rc != NO_ERROR) {
|
||||
ALOGE("%s: Failed to register the buffers of old stream,\
|
||||
rc = %d", __func__, rc);
|
||||
}
|
||||
ALOGV("%s: channel %p has %d buffers",
|
||||
__func__, channel, (*it)->buffer_set.num_buffers);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize mPendingRequestInfo and mPendnigBuffersMap */
|
||||
mPendingRequestsList.clear();
|
||||
// Initialize/Reset the pending buffers list
|
||||
|
@ -1124,63 +1120,9 @@ void QCamera3HardwareInterface::unblockRequestIfNecessary()
|
|||
*
|
||||
*==========================================================================*/
|
||||
int QCamera3HardwareInterface::registerStreamBuffers(
|
||||
const camera3_stream_buffer_set_t *buffer_set)
|
||||
const camera3_stream_buffer_set_t * /*buffer_set*/)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
pthread_mutex_lock(&mMutex);
|
||||
|
||||
if (buffer_set == NULL) {
|
||||
ALOGE("%s: Invalid buffer_set parameter.", __func__);
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (buffer_set->stream == NULL) {
|
||||
ALOGE("%s: Invalid stream parameter.", __func__);
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (buffer_set->num_buffers < 1) {
|
||||
ALOGE("%s: Invalid num_buffers %d.", __func__, buffer_set->num_buffers);
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (buffer_set->buffers == NULL) {
|
||||
ALOGE("%s: Invalid buffers parameter.", __func__);
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
camera3_stream_t *stream = buffer_set->stream;
|
||||
QCamera3Channel *channel = (QCamera3Channel *)stream->priv;
|
||||
|
||||
//set the buffer_set in the mStreamInfo array
|
||||
for (List<stream_info_t *>::iterator it = mStreamInfo.begin();
|
||||
it != mStreamInfo.end(); it++) {
|
||||
if ((*it)->stream == stream) {
|
||||
uint32_t numBuffers = buffer_set->num_buffers;
|
||||
(*it)->buffer_set.stream = buffer_set->stream;
|
||||
(*it)->buffer_set.num_buffers = numBuffers;
|
||||
(*it)->buffer_set.buffers = new buffer_handle_t*[numBuffers];
|
||||
if ((*it)->buffer_set.buffers == NULL) {
|
||||
ALOGE("%s: Failed to allocate buffer_handle_t*", __func__);
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
return -ENOMEM;
|
||||
}
|
||||
for (size_t j = 0; j < numBuffers; j++){
|
||||
(*it)->buffer_set.buffers[j] = buffer_set->buffers[j];
|
||||
}
|
||||
(*it)->registered = 1;
|
||||
}
|
||||
}
|
||||
rc = channel->registerBuffers(buffer_set->num_buffers, buffer_set->buffers);
|
||||
if (rc < 0) {
|
||||
ALOGE("%s: registerBUffers for stream %p failed", __func__, stream);
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
//Deprecated
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
|
@ -1213,6 +1155,32 @@ int QCamera3HardwareInterface::processCaptureRequest(
|
|||
return rc;
|
||||
}
|
||||
|
||||
if (mFirstRequest) {
|
||||
for (size_t i = 0; i < request->num_output_buffers; i++) {
|
||||
const camera3_stream_buffer_t& output = request->output_buffers[i];
|
||||
QCamera3Channel *channel = (QCamera3Channel *)output.stream->priv;
|
||||
rc = channel->registerBuffer(output.buffer);
|
||||
if (rc < 0) {
|
||||
ALOGE("%s: registerBuffer failed",
|
||||
__func__);
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
for (List<stream_info_t *>::iterator it = mStreamInfo.begin();
|
||||
it != mStreamInfo.end(); it++) {
|
||||
QCamera3Channel *channel = (QCamera3Channel *)(*it)->stream->priv;
|
||||
rc = channel->initialize();
|
||||
if (NO_ERROR != rc) {
|
||||
ALOGE("%s : Channel initialization failed %d", __func__, rc);
|
||||
mMetadataChannel->stop();
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t frameNumber = request->frame_number;
|
||||
uint32_t streamTypeMask = 0;
|
||||
|
||||
|
|
|
@ -185,15 +185,18 @@ int QCamera3Memory::getCnt() const
|
|||
* @bufDef : [output] reference to struct to store buffer definition
|
||||
* @index : [input] index of the buffer
|
||||
*
|
||||
* RETURN : none
|
||||
* RETURN : int32_t type of status
|
||||
* NO_ERROR -- success
|
||||
* none-zero failure code
|
||||
*==========================================================================*/
|
||||
void QCamera3Memory::getBufDef(const cam_frame_len_offset_t &offset,
|
||||
int32_t QCamera3Memory::getBufDef(const cam_frame_len_offset_t &offset,
|
||||
mm_camera_buf_def_t &bufDef, int index) const
|
||||
{
|
||||
if (!mBufferCount) {
|
||||
ALOGE("Memory not allocated");
|
||||
return;
|
||||
return NO_INIT;
|
||||
}
|
||||
|
||||
bufDef.fd = mMemInfo[index].fd;
|
||||
bufDef.frame_len = mMemInfo[index].size;
|
||||
bufDef.mem_info = (void *)this;
|
||||
|
@ -214,6 +217,8 @@ void QCamera3Memory::getBufDef(const cam_frame_len_offset_t &offset,
|
|||
bufDef.planes[i-1].reserved[0] +
|
||||
bufDef.planes[i-1].length;
|
||||
}
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
|
@ -584,104 +589,76 @@ QCamera3GrallocMemory::~QCamera3GrallocMemory()
|
|||
}
|
||||
|
||||
/*===========================================================================
|
||||
* FUNCTION : registerBuffers
|
||||
* FUNCTION : registerBuffer
|
||||
*
|
||||
* DESCRIPTION: register frameworks-allocated gralloc buffer_handle_t
|
||||
* DESCRIPTION: registers frameworks-allocated gralloc buffer_handle_t
|
||||
*
|
||||
* PARAMETERS :
|
||||
* @num_buffer : number of buffers to be registered
|
||||
* @buffers : array of buffer_handle_t pointers
|
||||
* @buffers : buffer_handle_t pointer
|
||||
*
|
||||
* RETURN : int32_t type of status
|
||||
* NO_ERROR -- success
|
||||
* none-zero failure code
|
||||
*==========================================================================*/
|
||||
int QCamera3GrallocMemory::registerBuffers(uint32_t num_buffers, buffer_handle_t **buffers)
|
||||
int QCamera3GrallocMemory::registerBuffer(buffer_handle_t *buffer)
|
||||
{
|
||||
status_t ret = NO_ERROR;
|
||||
struct ion_fd_data ion_info_fd;
|
||||
void *vaddr = NULL;
|
||||
ALOGV(" %s : E ", __FUNCTION__);
|
||||
|
||||
memset(&ion_info_fd, 0, sizeof(ion_info_fd));
|
||||
|
||||
|
||||
if (num_buffers > MM_CAMERA_MAX_NUM_FRAMES) {
|
||||
if (mBufferCount >= (MM_CAMERA_MAX_NUM_FRAMES - 1)) {
|
||||
ALOGE("%s: Number of buffers %d greater than what's supported %d",
|
||||
__func__, num_buffers, MM_CAMERA_MAX_NUM_FRAMES);
|
||||
__func__, mBufferCount, MM_CAMERA_MAX_NUM_FRAMES);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (size_t cnt = 0; cnt < num_buffers; cnt++) {
|
||||
if (buffers[cnt] == NULL) {
|
||||
ALOGE("%s: Invalid buffers[%d].", __func__, cnt);
|
||||
return -EINVAL;
|
||||
}
|
||||
mBufferHandle[cnt] = buffers[cnt];
|
||||
mPrivateHandle[cnt] =
|
||||
(struct private_handle_t *)(*mBufferHandle[cnt]);
|
||||
mMemInfo[cnt].main_ion_fd = open("/dev/ion", O_RDONLY);
|
||||
if (mMemInfo[cnt].main_ion_fd < 0) {
|
||||
ALOGE("%s: failed: could not open ion device", __func__);
|
||||
for(size_t i = 0; i < cnt; i++) {
|
||||
struct ion_handle_data ion_handle;
|
||||
memset(&ion_handle, 0, sizeof(ion_handle));
|
||||
ion_handle.handle = mMemInfo[i].handle;
|
||||
if (ioctl(mMemInfo[i].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) {
|
||||
ALOGE("%s: ion free failed", __func__);
|
||||
}
|
||||
close(mMemInfo[i].main_ion_fd);
|
||||
ALOGV("%s: cancel_buffer: hdl =%p", __func__, (*mBufferHandle[i]));
|
||||
mBufferHandle[i] = NULL;
|
||||
}
|
||||
memset(&mMemInfo, 0, sizeof(mMemInfo));
|
||||
ret = -ENOMEM;
|
||||
goto end;
|
||||
} else {
|
||||
ion_info_fd.fd = mPrivateHandle[cnt]->fd;
|
||||
if (ioctl(mMemInfo[cnt].main_ion_fd,
|
||||
ION_IOC_IMPORT, &ion_info_fd) < 0) {
|
||||
ALOGE("%s: ION import failed\n", __func__);
|
||||
for(size_t i = 0; i < cnt; i++) {
|
||||
struct ion_handle_data ion_handle;
|
||||
memset(&ion_handle, 0, sizeof(ion_handle));
|
||||
ion_handle.handle = mMemInfo[i].handle;
|
||||
if (ioctl(mMemInfo[i].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) {
|
||||
ALOGE("ion free failed");
|
||||
}
|
||||
close(mMemInfo[i].main_ion_fd);
|
||||
mBufferHandle[i] = NULL;
|
||||
}
|
||||
close(mMemInfo[cnt].main_ion_fd);
|
||||
memset(&mMemInfo, 0, sizeof(mMemInfo));
|
||||
ret = -ENOMEM;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
ALOGV("%s: idx = %d, fd = %d, size = %d, offset = %d",
|
||||
__func__, cnt, mPrivateHandle[cnt]->fd,
|
||||
mPrivateHandle[cnt]->size,
|
||||
mPrivateHandle[cnt]->offset);
|
||||
mMemInfo[cnt].fd =
|
||||
mPrivateHandle[cnt]->fd;
|
||||
mMemInfo[cnt].size =
|
||||
mPrivateHandle[cnt]->size;
|
||||
mMemInfo[cnt].handle = ion_info_fd.handle;
|
||||
|
||||
void *vaddr = mmap(NULL,
|
||||
mMemInfo[cnt].size,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED,
|
||||
mMemInfo[cnt].fd, 0);
|
||||
if (vaddr == MAP_FAILED) {
|
||||
for (int j = cnt-1; j >= 0; j --) {
|
||||
munmap(mPtr[cnt], mMemInfo[cnt].size);
|
||||
ret = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
} else
|
||||
mPtr[cnt] = vaddr;
|
||||
if (0 <= getMatchBufIndex((void *) buffer)) {
|
||||
ALOGV("%s: Buffer already registered", __func__);
|
||||
return ALREADY_EXISTS;
|
||||
}
|
||||
|
||||
mBufferHandle[mBufferCount] = buffer;
|
||||
mPrivateHandle[mBufferCount] =
|
||||
(struct private_handle_t *)(*mBufferHandle[mBufferCount]);
|
||||
mMemInfo[mBufferCount].main_ion_fd = open("/dev/ion", O_RDONLY);
|
||||
if (mMemInfo[mBufferCount].main_ion_fd < 0) {
|
||||
ALOGE("%s: failed: could not open ion device", __func__);
|
||||
ret = NO_MEMORY;
|
||||
goto end;
|
||||
} else {
|
||||
ion_info_fd.fd = mPrivateHandle[mBufferCount]->fd;
|
||||
if (ioctl(mMemInfo[mBufferCount].main_ion_fd,
|
||||
ION_IOC_IMPORT, &ion_info_fd) < 0) {
|
||||
ALOGE("%s: ION import failed\n", __func__);
|
||||
close(mMemInfo[mBufferCount].main_ion_fd);
|
||||
ret = NO_MEMORY;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
ALOGV("%s: idx = %d, fd = %d, size = %d, offset = %d",
|
||||
__func__, mBufferCount, mPrivateHandle[mBufferCount]->fd,
|
||||
mPrivateHandle[mBufferCount]->size,
|
||||
mPrivateHandle[mBufferCount]->offset);
|
||||
mMemInfo[mBufferCount].fd =
|
||||
mPrivateHandle[mBufferCount]->fd;
|
||||
mMemInfo[mBufferCount].size =
|
||||
mPrivateHandle[mBufferCount]->size;
|
||||
mMemInfo[mBufferCount].handle = ion_info_fd.handle;
|
||||
|
||||
vaddr = mmap(NULL,
|
||||
mMemInfo[mBufferCount].size,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED,
|
||||
mMemInfo[mBufferCount].fd, 0);
|
||||
if (vaddr == MAP_FAILED) {
|
||||
ret = NO_MEMORY;
|
||||
} else {
|
||||
mPtr[mBufferCount] = vaddr;
|
||||
mBufferCount++;
|
||||
}
|
||||
mBufferCount = num_buffers;
|
||||
|
||||
end:
|
||||
ALOGV(" %s : X ",__func__);
|
||||
|
|
|
@ -59,7 +59,7 @@ public:
|
|||
QCamera3Memory();
|
||||
virtual ~QCamera3Memory();
|
||||
|
||||
void getBufDef(const cam_frame_len_offset_t &offset,
|
||||
int32_t getBufDef(const cam_frame_len_offset_t &offset,
|
||||
mm_camera_buf_def_t &bufDef, int index) const;
|
||||
|
||||
protected:
|
||||
|
@ -107,7 +107,7 @@ public:
|
|||
QCamera3GrallocMemory();
|
||||
virtual ~QCamera3GrallocMemory();
|
||||
|
||||
int registerBuffers(uint32_t num_buffers, buffer_handle_t **buffers);
|
||||
int registerBuffer(buffer_handle_t *buffer);
|
||||
void unregisterBuffers();
|
||||
virtual int cacheOps(int index, unsigned int cmd);
|
||||
virtual int getRegFlags(uint8_t *regFlags) const;
|
||||
|
|
|
@ -168,6 +168,7 @@ QCamera3Stream::QCamera3Stream(uint32_t camHandle,
|
|||
mHandle(0),
|
||||
mCamOps(camOps),
|
||||
mStreamInfo(NULL),
|
||||
mMemOps(NULL),
|
||||
mNumBufs(0),
|
||||
mDataCB(NULL),
|
||||
mStreamInfoBuf(NULL),
|
||||
|
@ -265,6 +266,7 @@ int32_t QCamera3Stream::init(cam_stream_type_t streamType,
|
|||
mStreamInfo->stream_type = streamType;
|
||||
mStreamInfo->fmt = streamFormat;
|
||||
mStreamInfo->dim = streamDim;
|
||||
//mStreamInfo->num_bufs = minNumBuffers;
|
||||
|
||||
|
||||
|
||||
|
@ -493,7 +495,8 @@ void *QCamera3Stream::dataProcRoutine(void *data)
|
|||
mm_camera_buf_def_t* QCamera3Stream::getInternalFormatBuffer(int index)
|
||||
{
|
||||
mm_camera_buf_def_t *rc = NULL;
|
||||
if (index >= mNumBufs || mBufDefs == NULL) {
|
||||
if ((index >= mNumBufs) || (mBufDefs == NULL) ||
|
||||
(NULL == mBufDefs[index].mem_info)) {
|
||||
ALOGE("%s:Index out of range/no internal buffers yet", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -526,6 +529,27 @@ int32_t QCamera3Stream::bufDone(int index)
|
|||
if (index >= mNumBufs || mBufDefs == NULL)
|
||||
return BAD_INDEX;
|
||||
|
||||
if( NULL == mBufDefs[index].mem_info) {
|
||||
if (NULL == mMemOps) {
|
||||
ALOGE("%s: Camera operations not initialized", __func__);
|
||||
return NO_INIT;
|
||||
}
|
||||
|
||||
rc = mMemOps->map_ops(index, -1, mStreamBufs->getFd(index),
|
||||
mStreamBufs->getSize(index), mMemOps->userdata);
|
||||
if (rc < 0) {
|
||||
ALOGE("%s: Failed to map camera buffer %d", __func__, index);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[index], index);
|
||||
if (NO_ERROR != rc) {
|
||||
ALOGE("%s: Couldn't find camera buffer definition", __func__);
|
||||
mMemOps->unmap_ops(index, -1, mMemOps->userdata);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
rc = mCamOps->qbuf(mCamHandle, mChannelHandle, &mBufDefs[index]);
|
||||
if (rc < 0)
|
||||
return FAILED_TRANSACTION;
|
||||
|
@ -565,6 +589,7 @@ int32_t QCamera3Stream::getBufs(cam_frame_len_offset_t *offset,
|
|||
}
|
||||
|
||||
mFrameLenOffset = *offset;
|
||||
mMemOps = ops_tbl;
|
||||
|
||||
mStreamBufs = mChannel->getStreamBufs(mFrameLenOffset.frame_len);
|
||||
if (!mStreamBufs) {
|
||||
|
@ -572,7 +597,8 @@ int32_t QCamera3Stream::getBufs(cam_frame_len_offset_t *offset,
|
|||
return NO_MEMORY;
|
||||
}
|
||||
|
||||
for (int i = 0; i < mNumBufs; i++) {
|
||||
int registeredBuffers = mStreamBufs->getCnt();
|
||||
for (int i = 0; i < registeredBuffers; i++) {
|
||||
rc = ops_tbl->map_ops(i, -1, mStreamBufs->getFd(i),
|
||||
mStreamBufs->getSize(i), ops_tbl->userdata);
|
||||
if (rc < 0) {
|
||||
|
@ -588,30 +614,32 @@ int32_t QCamera3Stream::getBufs(cam_frame_len_offset_t *offset,
|
|||
regFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs);
|
||||
if (!regFlags) {
|
||||
ALOGE("%s: Out of memory", __func__);
|
||||
for (int i = 0; i < mNumBufs; i++) {
|
||||
for (int i = 0; i < registeredBuffers; i++) {
|
||||
ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
|
||||
}
|
||||
return NO_MEMORY;
|
||||
}
|
||||
memset(regFlags, 0, sizeof(uint8_t) * mNumBufs);
|
||||
|
||||
mBufDefs = (mm_camera_buf_def_t *)malloc(mNumBufs * sizeof(mm_camera_buf_def_t));
|
||||
if (mBufDefs == NULL) {
|
||||
ALOGE("%s: Failed to allocate mm_camera_buf_def_t %d", __func__, rc);
|
||||
for (int i = 0; i < mNumBufs; i++) {
|
||||
for (int i = 0; i < registeredBuffers; i++) {
|
||||
ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
|
||||
}
|
||||
free(regFlags);
|
||||
regFlags = NULL;
|
||||
return INVALID_OPERATION;
|
||||
}
|
||||
for (int i = 0; i < mNumBufs; i++) {
|
||||
memset(mBufDefs, 0, mNumBufs * sizeof(mm_camera_buf_def_t));
|
||||
for (int i = 0; i < registeredBuffers; i++) {
|
||||
mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[i], i);
|
||||
}
|
||||
|
||||
rc = mStreamBufs->getRegFlags(regFlags);
|
||||
if (rc < 0) {
|
||||
ALOGE("%s: getRegFlags failed %d", __func__, rc);
|
||||
for (int i = 0; i < mNumBufs; i++) {
|
||||
for (int i = 0; i < registeredBuffers; i++) {
|
||||
ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
|
||||
}
|
||||
free(mBufDefs);
|
||||
|
@ -643,9 +671,11 @@ int32_t QCamera3Stream::putBufs(mm_camera_map_unmap_ops_tbl_t *ops_tbl)
|
|||
{
|
||||
int rc = NO_ERROR;
|
||||
for (int i = 0; i < mNumBufs; i++) {
|
||||
rc = ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
|
||||
if (rc < 0) {
|
||||
ALOGE("%s: map_stream_buf failed: %d", __func__, rc);
|
||||
if (NULL != mBufDefs[i].mem_info) {
|
||||
rc = ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
|
||||
if (rc < 0) {
|
||||
ALOGE("%s: map_stream_buf failed: %d", __func__, rc);
|
||||
}
|
||||
}
|
||||
}
|
||||
mBufDefs = NULL; // mBufDefs just keep a ptr to the buffer
|
||||
|
|
|
@ -91,6 +91,7 @@ private:
|
|||
mm_camera_ops_t *mCamOps;
|
||||
cam_stream_info_t *mStreamInfo; // ptr to stream info buf
|
||||
mm_camera_stream_mem_vtbl_t mMemVtbl;
|
||||
mm_camera_map_unmap_ops_tbl_t *mMemOps;
|
||||
uint8_t mNumBufs;
|
||||
stream_cb_routine mDataCB;
|
||||
void *mUserData;
|
||||
|
|
|
@ -348,6 +348,9 @@ typedef struct {
|
|||
offset_x, offset_y, stride, scanline, plane offset */
|
||||
cam_stream_buf_plane_info_t buf_planes;
|
||||
|
||||
/* number of stream bufs will be allocated */
|
||||
//uint8_t num_bufs;
|
||||
|
||||
/* streaming type */
|
||||
cam_streaming_mode_t streaming_mode;
|
||||
/* num of frames needs to be generated.
|
||||
|
|
|
@ -225,6 +225,8 @@ typedef struct mm_stream {
|
|||
|
||||
mm_camera_stream_mem_vtbl_t mem_vtbl; /* mem ops tbl */
|
||||
|
||||
mm_camera_map_unmap_ops_tbl_t map_ops;
|
||||
|
||||
int8_t queued_buffer_count;
|
||||
} mm_stream_t;
|
||||
|
||||
|
|
|
@ -1412,7 +1412,6 @@ int32_t mm_stream_init_bufs(mm_stream_t * my_obj)
|
|||
{
|
||||
int32_t i, rc = 0;
|
||||
uint8_t *reg_flags = NULL;
|
||||
mm_camera_map_unmap_ops_tbl_t ops_tbl;
|
||||
CDBG("%s: E, my_handle = 0x%x, fd = %d, state = %d",
|
||||
__func__, my_obj->my_hdl, my_obj->fd, my_obj->state);
|
||||
|
||||
|
@ -1421,15 +1420,15 @@ int32_t mm_stream_init_bufs(mm_stream_t * my_obj)
|
|||
mm_stream_deinit_bufs(my_obj);
|
||||
}
|
||||
|
||||
ops_tbl.map_ops = mm_stream_map_buf_ops;
|
||||
ops_tbl.unmap_ops = mm_stream_unmap_buf_ops;
|
||||
ops_tbl.userdata = my_obj;
|
||||
my_obj->map_ops.map_ops = mm_stream_map_buf_ops;
|
||||
my_obj->map_ops.unmap_ops = mm_stream_unmap_buf_ops;
|
||||
my_obj->map_ops.userdata = my_obj;
|
||||
|
||||
rc = my_obj->mem_vtbl.get_bufs(&my_obj->frame_offset,
|
||||
&my_obj->buf_num,
|
||||
®_flags,
|
||||
&my_obj->buf,
|
||||
&ops_tbl,
|
||||
&my_obj->map_ops,
|
||||
my_obj->mem_vtbl.user_data);
|
||||
|
||||
if (0 != rc) {
|
||||
|
|
Loading…
Reference in New Issue