blob: 5d1b71f6044a4137e17327a9ff137c6297d5033a [file] [log] [blame]
/* Copyright (c) 2012, The Linux Foundataion. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#define LOG_TAG "QCameraChannel"
#include <utils/Log.h>
#include <utils/Errors.h>
#include "QCameraChannel.h"
using namespace android;
namespace qcamera {
QCameraChannel::QCameraChannel(uint32_t cam_handle,
mm_camera_ops_t *cam_ops)
{
m_camHandle = cam_handle;
m_camOps = cam_ops;
m_handle = 0;
m_numStreams = 0;
memset(mStreams, 0, sizeof(mStreams));
}
QCameraChannel::QCameraChannel()
{
m_camHandle = 0;
m_camOps = NULL;
m_handle = 0;
m_numStreams = 0;
memset(mStreams, 0, sizeof(mStreams));
}
QCameraChannel::~QCameraChannel()
{
for (int i = 0; i < m_numStreams; i++) {
if (mStreams[i] != NULL) {
delete mStreams[i];
mStreams[i] = 0;
}
}
m_numStreams = 0;
m_camOps->delete_channel(m_camHandle, m_handle);
m_handle = 0;
}
int32_t QCameraChannel::init(mm_camera_channel_attr_t *attr,
mm_camera_buf_notify_t dataCB,
void *userData)
{
m_handle = m_camOps->add_channel(m_camHandle,
attr,
dataCB,
userData);
if (m_handle == 0) {
ALOGE("%s: Add channel failed", __func__);
return UNKNOWN_ERROR;
}
return NO_ERROR;
}
int32_t QCameraChannel::addStream(QCameraAllocator &allocator,
cam_stream_type_t stream_type,
cam_padding_info_t *paddingInfo,
stream_cb_routine stream_cb,
void *userdata)
{
int32_t rc = NO_ERROR;
if (m_numStreams >= MAX_STREAM_NUM_IN_BUNDLE) {
ALOGE("%s: stream number (%d) exceeds max limit (%d)",
__func__, m_numStreams, MAX_STREAM_NUM_IN_BUNDLE);
return BAD_VALUE;
}
QCameraStream *pStream = new QCameraStream(allocator,
m_camHandle,
m_handle,
m_camOps,
paddingInfo);
if (pStream == NULL) {
ALOGE("%s: No mem for Stream", __func__);
return NO_MEMORY;
}
rc = pStream->init(stream_type, stream_cb, userdata);
if (rc == 0) {
mStreams[m_numStreams] = pStream;
m_numStreams++;
} else {
delete pStream;
}
return rc;
}
int32_t QCameraChannel::start()
{
int32_t rc = NO_ERROR;
for (int i = 0; i < m_numStreams; i++) {
if (mStreams[i] != NULL) {
rc = mStreams[i]->start();
}
}
rc = m_camOps->start_channel(m_camHandle, m_handle);
return rc;
}
int32_t QCameraChannel::stop()
{
int32_t rc = NO_ERROR;
rc = m_camOps->stop_channel(m_camHandle, m_handle);
for (int i = 0; i < m_numStreams; i++) {
if (mStreams[i] != NULL) {
mStreams[i]->stop();
}
}
return rc;
}
int32_t QCameraChannel::bufDone(mm_camera_super_buf_t *recvd_frame)
{
int32_t rc = NO_ERROR;
for (int i = 0; i < recvd_frame->num_bufs; i++) {
if (recvd_frame->bufs[i] != NULL) {
for (int j = 0; j < m_numStreams; j++) {
if (mStreams[j] != NULL &&
mStreams[j]->getMyHandle() == recvd_frame->bufs[i]->stream_id) {
rc = mStreams[j]->bufDone(recvd_frame->bufs[j]->buf_idx);
break; // break loop j
}
}
}
}
return rc;
}
int32_t QCameraChannel::processZoomDone(preview_stream_ops_t *previewWindow)
{
int32_t rc = NO_ERROR;
for (int i = 0; i < m_numStreams; i++) {
if (mStreams[i] != NULL) {
rc = mStreams[i]->processZoomDone(previewWindow);
}
}
return rc;
}
QCameraStream *QCameraChannel::getStreamByHandle(uint32_t streamHandle)
{
for (int i = 0; i < m_numStreams; i++) {
if (mStreams[i] != NULL && mStreams[i]->getMyHandle() == streamHandle) {
return mStreams[i];
}
}
return NULL;
}
QCameraPicChannel::QCameraPicChannel(uint32_t cam_handle,
mm_camera_ops_t *cam_ops) :
QCameraChannel(cam_handle, cam_ops)
{
}
QCameraPicChannel::QCameraPicChannel()
{
}
QCameraPicChannel::~QCameraPicChannel()
{
}
int32_t QCameraPicChannel::takePicture(uint8_t num_of_snapshot)
{
int32_t rc = m_camOps->request_super_buf(m_camHandle,
m_handle,
num_of_snapshot);
return rc;
}
int32_t QCameraPicChannel::cancelPicture()
{
int32_t rc = m_camOps->cancel_super_buf_request(m_camHandle, m_handle);
return rc;
}
QCameraVideoChannel::QCameraVideoChannel(uint32_t cam_handle,
mm_camera_ops_t *cam_ops) :
QCameraChannel(cam_handle, cam_ops)
{
}
QCameraVideoChannel::QCameraVideoChannel()
{
}
QCameraVideoChannel::~QCameraVideoChannel()
{
}
int32_t QCameraVideoChannel::releaseFrame(const void * opaque, bool isMetaData)
{
QCameraStream *pVideoStream = NULL;
for (int i = 0; i < m_numStreams; i++) {
if (mStreams[i] != NULL && mStreams[i]->isTypeOf(CAM_STREAM_TYPE_VIDEO)) {
pVideoStream = mStreams[i];
break;
}
}
if (NULL == pVideoStream) {
ALOGE("%s: No video stream in the channel", __func__);
return BAD_VALUE;
}
int32_t rc = pVideoStream->bufDone(opaque, isMetaData);
return rc;
}
QCameraReprocessChannel::QCameraReprocessChannel(uint32_t cam_handle,
mm_camera_ops_t *cam_ops) :
QCameraChannel(cam_handle, cam_ops)
{
}
QCameraReprocessChannel::QCameraReprocessChannel()
{
}
QCameraReprocessChannel::~QCameraReprocessChannel()
{
}
int32_t QCameraReprocessChannel::doReprocess(mm_camera_super_buf_t *frame)
{
int32_t rc = 0;
if (m_numStreams < 1) {
ALOGE("%s: No reprocess stream is created", __func__);
return -1;
}
rc = m_camOps->map_stream_buf(m_camHandle,
m_handle,
mStreams[0]->getMyHandle(),
CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF,
0,
-1,
frame->bufs[0]->fd,
frame->bufs[0]->frame_len);
return rc;
}
}; // namespace qcamera