/*
** Copyright (c) 2011-2012 The Linux Foundation. All rights reserved.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*#error uncomment this for compiler test!*/
#define ALOG_NDEBUG 0
#define ALOG_NIDEBUG 0
#define LOG_TAG __FILE__
#include <utils/Log.h>
#include <utils/threads.h>
#include "QCameraStream.h"
/* QCameraStream class implementation goes here*/
/* following code implement the control logic of this class*/
namespace android {
StreamQueue::StreamQueue(){
mInitialized = false;
}
StreamQueue::~StreamQueue(){
flush();
}
void StreamQueue::init(){
Mutex::Autolock l(&mQueueLock);
mInitialized = true;
mQueueWait.signal();
}
void StreamQueue::deinit(){
Mutex::Autolock l(&mQueueLock);
mInitialized = false;
mQueueWait.signal();
}
bool StreamQueue::isInitialized(){
Mutex::Autolock l(&mQueueLock);
return mInitialized;
}
bool StreamQueue::enqueue(
void * element){
Mutex::Autolock l(&mQueueLock);
if(mInitialized == false)
return false;
mContainer.add(element);
mQueueWait.signal();
return true;
}
bool StreamQueue::isEmpty(){
return (mInitialized && mContainer.isEmpty());
}
void* StreamQueue::dequeue(){
void *frame;
mQueueLock.lock();
while(mInitialized && mContainer.isEmpty()){
mQueueWait.wait(mQueueLock);
}
if(!mInitialized){
mQueueLock.unlock();
return NULL;
}
frame = mContainer.itemAt(0);
mContainer.removeAt(0);
mQueueLock.unlock();
return frame;
}
void StreamQueue::flush(){
Mutex::Autolock l(&mQueueLock);
mContainer.clear();
}
// ---------------------------------------------------------------------------
// QCameraStream
// ---------------------------------------------------------------------------
/* initialize a streaming channel*/
status_t QCameraStream::initChannel(int cameraId,
uint32_t ch_type_mask)
{
#if 0
int rc = MM_CAMERA_OK;
int i;
status_t ret = NO_ERROR;
int width = 0; /* width of channel */
int height = 0; /* height of channel */
cam_ctrl_dimension_t dim;
mm_camera_ch_image_fmt_parm_t fmt;
memset(&dim, 0, sizeof(cam_ctrl_dimension_t));
rc = cam_config_get_parm(cameraId, MM_CAMERA_PARM_DIMENSION, &dim);
if (MM_CAMERA_OK != rc) {
ALOGE("%s: error - can't get camera dimension!", __func__);
ALOGE("%s: X", __func__);
return BAD_VALUE;
}
if(MM_CAMERA_CH_PREVIEW_MASK & ch_type_mask) {
rc = cam_ops_ch_acquire(cameraId, MM_CAMERA_CH_PREVIEW);
ALOGV("%s:ch_acquire MM_CAMERA_CH_PREVIEW, rc=%d\n",__func__, rc);
if(MM_CAMERA_OK != rc) {
ALOGE("%s: preview channel acquir error =%d\n", __func__, rc);
ALOGE("%s: X", __func__);
return BAD_VALUE;
}
else{
memset(&fmt, 0, sizeof(mm_camera_ch_image_fmt_parm_t));
fmt.ch_type = MM_CAMERA_CH_PREVIEW;
fmt.def.fmt = CAMERA_YUV_420_NV12; //dim.prev_format;
fmt.def.dim.width = dim.display_width;
fmt.def.dim.height = dim.display_height;
ALOGV("%s: preview channel fmt = %d", __func__,
dim.prev_format);
ALOGV("%s: preview channel resolution = %d X %d", __func__,
dim.display_width, dim.display_height);
rc = cam_config_set_parm(cameraId, MM_CAMERA_PARM_CH_IMAGE_FMT, &fmt);
ALOGV("%s: preview MM_CAMERA_PARM_CH_IMAGE_FMT rc = %d\n", __func__, rc);
if(MM_CAMERA_OK != rc) {
ALOGE("%s:set preview channel format err=%d\n", __func__, ret);
ALOGE("%s: X", __func__);
ret = BAD_VALUE;
}
}
}
if(MM_CAMERA_CH_VIDEO_MASK & ch_type_mask)
{
rc = cam_ops_ch_acquire(cameraId, MM_CAMERA_CH_VIDEO);
ALOGV("%s:ch_acquire MM_CAMERA_CH_VIDEO, rc=%d\n",__func__, rc);
if(MM_CAMERA_OK != rc) {
ALOGE("%s: video channel acquir error =%d\n", __func__, rc);
ALOGE("%s: X", __func__);
ret = BAD_VALUE;
}
else {
memset(&fmt, 0, sizeof(mm_camera_ch_image_fmt_parm_t));
fmt.ch_type = MM_CAMERA_CH_VIDEO;
fmt.video.video.fmt = CAMERA_YUV_420_NV12; //dim.enc_format;
fmt.video.video.dim.width = dim.video_width;
fmt.video.video.dim.height = dim.video_height;
ALOGV("%s: video channel fmt = %d", __func__,
dim.enc_format);
ALOGV("%s: video channel resolution = %d X %d", __func__,
dim.video_width, dim.video_height);
rc = cam_config_set_parm(cameraId, MM_CAMERA_PARM_CH_IMAGE_FMT, &fmt);
ALOGV("%s: video MM_CAMERA_PARM_CH_IMAGE_FMT rc = %d\n", __func__, rc);
if(MM_CAMERA_OK != rc) {
ALOGE("%s:set video channel format err=%d\n", __func__, rc);
ALOGE("%s: X", __func__);
ret= BAD_VALUE;
}
}
} /*MM_CAMERA_CH_VIDEO*/
#endif
int rc = MM_CAMERA_OK;
status_t ret = NO_ERROR;
mm_camera_op_mode_type_t op_mode=MM_CAMERA_OP_MODE_VIDEO;
int i;
ALOGV("QCameraStream::initChannel : E");
if(MM_CAMERA_CH_PREVIEW_MASK & ch_type_mask){
rc = cam_ops_ch_acquire(cameraId, MM_CAMERA_CH_PREVIEW);
ALOGV("%s:ch_acquire MM_CAMERA_CH_PREVIEW, rc=%d\n",__func__, rc);
if(MM_CAMERA_OK != rc) {
ALOGE("%s: preview channel acquir error =%d\n", __func__, rc);
ALOGV("%s: X", __func__);
return BAD_VALUE;
}
/*Callback register*/
/* register a notify into the mmmm_camera_t object*/
/* ret = cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_PREVIEW,
preview_notify_cb,
this);
ALOGV("Buf notify MM_CAMERA_CH_PREVIEW, rc=%d\n",rc);*/
}else if(MM_CAMERA_CH_VIDEO_MASK & ch_type_mask){
rc = cam_ops_ch_acquire(cameraId, MM_CAMERA_CH_VIDEO);
ALOGV("%s:ch_acquire MM_CAMERA_CH_VIDEO, rc=%d\n",__func__, rc);
if(MM_CAMERA_OK != rc) {
ALOGE("%s: preview channel acquir error =%d\n", __func__, rc);
ALOGV("%s: X", __func__);
return BAD_VALUE;
}
/*Callback register*/
/* register a notify into the mmmm_camera_t object*/
/*ret = cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_VIDEO,
record_notify_cb,
this);
ALOGV("Buf notify MM_CAMERA_CH_VIDEO, rc=%d\n",rc);*/
}
ret = (MM_CAMERA_OK==rc)? NO_ERROR : BAD_VALUE;
ALOGV("%s: X, ret = %d", __func__, ret);
return ret;
}
status_t QCameraStream::deinitChannel(int cameraId,
mm_camera_channel_type_t ch_type)
{
int rc = MM_CAMERA_OK;
ALOGV("%s: E, channel = %d\n", __func__, ch_type);
if (MM_CAMERA_CH_MAX <= ch_type) {
ALOGE("%s: X: BAD_VALUE", __func__);
return BAD_VALUE;
}
cam_ops_ch_release(cameraId, ch_type);
ALOGV("%s: X, channel = %d\n", __func__, ch_type);
return NO_ERROR;
}
status_t QCameraStream::setMode(int enable) {
ALOGV("%s :myMode %x ", __func__, myMode);
if (enable) {
myMode = (camera_mode_t)(myMode | CAMERA_ZSL_MODE);
} else {
myMode = (camera_mode_t)(myMode & ~CAMERA_ZSL_MODE);
}
return NO_ERROR;
}
status_t QCameraStream::setFormat(uint8_t ch_type_mask, cam_format_t previewFmt)
{
int rc = MM_CAMERA_OK;
status_t ret = NO_ERROR;
int width = 0; /* width of channel */
int height = 0; /* height of channel */
cam_ctrl_dimension_t dim;
mm_camera_ch_image_fmt_parm_t fmt;
ALOGV("%s: E",__func__);
memset(&dim, 0, sizeof(cam_ctrl_dimension_t));
rc = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION, &dim);
if (MM_CAMERA_OK != rc) {
ALOGE("%s: error - can't get camera dimension!", __func__);
ALOGV("%s: X", __func__);
return BAD_VALUE;
}
char mDeviceName[PROPERTY_VALUE_MAX];
property_get("ro.product.device",mDeviceName," ");
memset(&fmt, 0, sizeof(mm_camera_ch_image_fmt_parm_t));
if(MM_CAMERA_CH_PREVIEW_MASK & ch_type_mask){
fmt.ch_type = MM_CAMERA_CH_PREVIEW;
fmt.def.fmt = (cam_format_t)previewFmt;
fmt.def.dim.width = dim.display_width;
fmt.def.dim.height = dim.display_height;
}else if(MM_CAMERA_CH_VIDEO_MASK & ch_type_mask){
fmt.ch_type = MM_CAMERA_CH_VIDEO;
fmt.video.video.fmt = CAMERA_YUV_420_NV21; //dim.enc_format;
fmt.video.video.dim.width = dim.video_width;
fmt.video.video.dim.height = dim.video_height;
}/*else if(MM_CAMERA_CH_SNAPSHOT_MASK & ch_type_mask){
if(mHalCamCtrl->isRawSnapshot()) {
fmt.ch_type = MM_CAMERA_CH_RAW;
fmt.def.fmt = CAMERA_BAYER_SBGGR10;
fmt.def.dim.width = dim.raw_picture_width;
fmt.def.dim.height = dim.raw_picture_height;
}else{
//Jpeg???
fmt.ch_type = MM_CAMERA_CH_SNAPSHOT;
fmt.snapshot.main.fmt = dim.main_img_format;
fmt.snapshot.main.dim.width = dim.picture_width;
fmt.snapshot.main.dim.height = dim.picture_height;
fmt.snapshot.thumbnail.fmt = dim.thumb_format;
fmt.snapshot.thumbnail.dim.width = dim.ui_thumbnail_width;
fmt.snapshot.thumbnail.dim.height = dim.ui_thumbnail_height;
}
}*/
rc = cam_config_set_parm(mCameraId, MM_CAMERA_PARM_CH_IMAGE_FMT, &fmt);
ALOGV("%s: Stream MM_CAMERA_PARM_CH_IMAGE_FMT rc = %d\n", __func__, rc);
if(MM_CAMERA_OK != rc) {
ALOGE("%s:set stream channel format err=%d\n", __func__, ret);
ALOGV("%s: X", __func__);
ret = BAD_VALUE;
}
ALOGV("%s: X",__func__);
return ret;
}
QCameraStream::QCameraStream (){
mInit = false;
mActive = false;
/* memset*/
memset(&mCrop, 0, sizeof(mm_camera_ch_crop_t));
}
QCameraStream::QCameraStream (int cameraId, camera_mode_t mode)
:mCameraId(cameraId),
myMode(mode)
{
mInit = false;
mActive = false;
/* memset*/
memset(&mCrop, 0, sizeof(mm_camera_ch_crop_t));
}
QCameraStream::~QCameraStream () {;}
status_t QCameraStream::init() {
return NO_ERROR;
}
status_t QCameraStream::start() {
return NO_ERROR;
}
void QCameraStream::stop() {
return;
}
void QCameraStream::release() {
return;
}
void QCameraStream::setHALCameraControl(QCameraHardwareInterface* ctrl) {
/* provide a frame data user,
for the queue monitor thread to call the busy queue is not empty*/
mHalCamCtrl = ctrl;
}
}; // namespace android