blob: 658bd84c62bbb74e9fd894ceda157d1beefc328e [file] [log] [blame]
Iliyan Malchev6d016452013-03-27 16:27:56 -07001/*
2** Copyright (c) 2011-2012 The Linux Foundation. All rights reserved.
3**
4** Licensed under the Apache License, Version 2.0 (the "License");
5** you may not use this file except in compliance with the License.
6** You may obtain a copy of the License at
7**
8** http://www.apache.org/licenses/LICENSE-2.0
9**
10** Unless required by applicable law or agreed to in writing, software
11** distributed under the License is distributed on an "AS IS" BASIS,
12** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13** See the License for the specific language governing permissions and
14** limitations under the License.
15*/
16
17/*#error uncomment this for compiler test!*/
18
19#define LOG_TAG "QCameraHWI_Preview"
20#include <utils/Log.h>
21#include <utils/threads.h>
22#include <fcntl.h>
23#include <sys/mman.h>
24#include "QCameraHAL.h"
25#include "QCameraHWI.h"
26#include <genlock.h>
27#include <gralloc_priv.h>
28
29#define UNLIKELY(exp) __builtin_expect(!!(exp), 0)
30
31/* QCameraHWI_Preview class implementation goes here*/
32/* following code implement the preview mode's image capture & display logic of this class*/
33
34namespace android {
35
36// ---------------------------------------------------------------------------
37// Preview Callback
38// ---------------------------------------------------------------------------
39static void preview_notify_cb(mm_camera_ch_data_buf_t *frame,
40 void *user_data)
41{
42 QCameraStream_preview *pme = (QCameraStream_preview *)user_data;
43 mm_camera_ch_data_buf_t *bufs_used = 0;
44 ALOGV("%s: E", __func__);
45 /* for peview data, there is no queue, so directly use*/
46 if(pme==NULL) {
47 ALOGE("%s: X : Incorrect cookie",__func__);
48 /*Call buf done*/
49 return;
50 }
51
52 pme->processPreviewFrame(frame);
53 ALOGV("%s: X", __func__);
54}
55
56status_t QCameraStream_preview::setPreviewWindow(preview_stream_ops_t* window)
57{
58 status_t retVal = NO_ERROR;
59 ALOGV(" %s: E ", __FUNCTION__);
60 if( window == NULL) {
61 ALOGW(" Setting NULL preview window ");
62 /* TODO: Current preview window will be invalidated.
63 * Release all the buffers back */
64 // relinquishBuffers();
65 }
66 Mutex::Autolock lock(mStopCallbackLock);
67 mPreviewWindow = window;
68 ALOGV(" %s : X ", __FUNCTION__ );
69 return retVal;
70}
71
72status_t QCameraStream_preview::getBufferFromSurface()
73{
74 int err = 0;
75 int numMinUndequeuedBufs = 0;
76 int format = 0;
77 status_t ret = NO_ERROR;
78 int gralloc_usage;
79
80 ALOGV(" %s : E ", __FUNCTION__);
81
82 if( mPreviewWindow == NULL) {
83 ALOGE("%s: mPreviewWindow = NULL", __func__);
84 return INVALID_OPERATION;
85 }
86 cam_ctrl_dimension_t dim;
87
88 //mDisplayLock.lock();
89 ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION,&dim);
90
91 format = mHalCamCtrl->getPreviewFormatInfo().Hal_format;
92 if(ret != NO_ERROR) {
93 ALOGE("%s: display format %d is not supported", __func__, dim.prev_format);
94 goto end;
95 }
96 numMinUndequeuedBufs = 0;
97 if(mPreviewWindow->get_min_undequeued_buffer_count) {
98 err = mPreviewWindow->get_min_undequeued_buffer_count(mPreviewWindow, &numMinUndequeuedBufs);
99 if (err != 0) {
100 ALOGE("get_min_undequeued_buffer_count failed: %s (%d)",
101 strerror(-err), -err);
102 ret = UNKNOWN_ERROR;
103 goto end;
104 }
105 }
106 mHalCamCtrl->mPreviewMemoryLock.lock();
107 mHalCamCtrl->mPreviewMemory.buffer_count = kPreviewBufferCount + numMinUndequeuedBufs;
108 if(mHalCamCtrl->isZSLMode()) {
109 if(mHalCamCtrl->getZSLQueueDepth() > numMinUndequeuedBufs)
110 mHalCamCtrl->mPreviewMemory.buffer_count +=
111 mHalCamCtrl->getZSLQueueDepth() - numMinUndequeuedBufs;
112 }
113 err = mPreviewWindow->set_buffer_count(mPreviewWindow, mHalCamCtrl->mPreviewMemory.buffer_count );
114 if (err != 0) {
115 ALOGE("set_buffer_count failed: %s (%d)",
116 strerror(-err), -err);
117 ret = UNKNOWN_ERROR;
118 goto end;
119 }
120 err = mPreviewWindow->set_buffers_geometry(mPreviewWindow,
121 dim.display_width, dim.display_height, format);
122 if (err != 0) {
123 ALOGE("set_buffers_geometry failed: %s (%d)",
124 strerror(-err), -err);
125 ret = UNKNOWN_ERROR;
126 goto end;
127 }
128
129 ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_VFE_OUTPUT_ENABLE, &mVFEOutputs);
130 if(ret != MM_CAMERA_OK) {
131 ALOGE("get parm MM_CAMERA_PARM_VFE_OUTPUT_ENABLE failed");
132 ret = BAD_VALUE;
133 goto end;
134 }
135
136 //as software encoder is used to encode 720p, to enhance the performance
137 //cashed pmem is used here
138 if(mVFEOutputs == 1 && dim.display_height == 720)
Shuzhen Wanga3f5ef82013-05-08 13:31:41 -0700139 gralloc_usage = GRALLOC_USAGE_HW_CAMERA_WRITE | CAMERA_GRALLOC_HEAP_ID | CAMERA_GRALLOC_FALLBACK_HEAP_ID;
Iliyan Malchev6d016452013-03-27 16:27:56 -0700140 else
Shuzhen Wanga3f5ef82013-05-08 13:31:41 -0700141 gralloc_usage = GRALLOC_USAGE_HW_CAMERA_WRITE | CAMERA_GRALLOC_HEAP_ID | CAMERA_GRALLOC_FALLBACK_HEAP_ID |
Iliyan Malchev6d016452013-03-27 16:27:56 -0700142 CAMERA_GRALLOC_CACHING_ID;
143 err = mPreviewWindow->set_usage(mPreviewWindow, gralloc_usage);
144 if(err != 0) {
145 /* set_usage error out */
146 ALOGE("%s: set_usage rc = %d", __func__, err);
147 ret = UNKNOWN_ERROR;
148 goto end;
149 }
150 ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_HFR_FRAME_SKIP, &mHFRFrameSkip);
151 if(ret != MM_CAMERA_OK) {
152 ALOGE("get parm MM_CAMERA_PARM_HFR_FRAME_SKIP failed");
153 ret = BAD_VALUE;
154 goto end;
155 }
156 for (int cnt = 0; cnt < mHalCamCtrl->mPreviewMemory.buffer_count; cnt++) {
157 int stride;
158 err = mPreviewWindow->dequeue_buffer(mPreviewWindow,
159 &mHalCamCtrl->mPreviewMemory.buffer_handle[cnt],
160 &mHalCamCtrl->mPreviewMemory.stride[cnt]);
161 if(!err) {
162 ALOGV("%s: dequeue buf hdl =%p", __func__, *mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]);
163 err = mPreviewWindow->lock_buffer(this->mPreviewWindow,
164 mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]);
165 // lock the buffer using genlock
166 ALOGV("%s: camera call genlock_lock, hdl=%p", __FUNCTION__, (*mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]));
167 if (GENLOCK_NO_ERROR != genlock_lock_buffer((native_handle_t *)(*mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]),
168 GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) {
169 ALOGV("%s: genlock_lock_buffer(WRITE) failed", __FUNCTION__);
170 mHalCamCtrl->mPreviewMemory.local_flag[cnt] = BUFFER_UNLOCKED;
171 //mHalCamCtrl->mPreviewMemoryLock.unlock();
172 //return -EINVAL;
173 } else {
174 ALOGV("%s: genlock_lock_buffer hdl =%p", __FUNCTION__, *mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]);
175 mHalCamCtrl->mPreviewMemory.local_flag[cnt] = BUFFER_LOCKED;
176 }
177 } else {
178 mHalCamCtrl->mPreviewMemory.local_flag[cnt] = BUFFER_NOT_OWNED;
179 ALOGV("%s: dequeue_buffer idx = %d err = %d", __func__, cnt, err);
180 }
181
182 ALOGV("%s: dequeue buf: %p\n", __func__, mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]);
183
184 if(err != 0) {
185 ALOGE("%s: dequeue_buffer failed: %s (%d)", __func__,
186 strerror(-err), -err);
187 ret = UNKNOWN_ERROR;
188 for(int i = 0; i < cnt; i++) {
189 if (BUFFER_LOCKED == mHalCamCtrl->mPreviewMemory.local_flag[i]) {
190 ALOGV("%s: camera call genlock_unlock", __FUNCTION__);
191 if (GENLOCK_FAILURE == genlock_unlock_buffer((native_handle_t *)
192 (*(mHalCamCtrl->mPreviewMemory.buffer_handle[i])))) {
193 ALOGE("%s: genlock_unlock_buffer failed: hdl =%p", __FUNCTION__, (*(mHalCamCtrl->mPreviewMemory.buffer_handle[i])) );
194 //mHalCamCtrl->mPreviewMemoryLock.unlock();
195 //return -EINVAL;
196 } else {
197 mHalCamCtrl->mPreviewMemory.local_flag[i] = BUFFER_UNLOCKED;
198 }
199 }
200 if( mHalCamCtrl->mPreviewMemory.local_flag[i] != BUFFER_NOT_OWNED) {
201 err = mPreviewWindow->cancel_buffer(mPreviewWindow,
202 mHalCamCtrl->mPreviewMemory.buffer_handle[i]);
203 }
204 mHalCamCtrl->mPreviewMemory.local_flag[i] = BUFFER_NOT_OWNED;
205 ALOGV("%s: cancel_buffer: hdl =%p", __func__, (*mHalCamCtrl->mPreviewMemory.buffer_handle[i]));
206 mHalCamCtrl->mPreviewMemory.buffer_handle[i] = NULL;
207 }
208 memset(&mHalCamCtrl->mPreviewMemory, 0, sizeof(mHalCamCtrl->mPreviewMemory));
209 goto end;
210 }
211
212 mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt] =
213 (struct private_handle_t *)(*mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]);
214#ifdef USE_ION
215 mHalCamCtrl->mPreviewMemory.main_ion_fd[cnt] = open("/dev/ion", O_RDONLY);
216 if (mHalCamCtrl->mPreviewMemory.main_ion_fd[cnt] < 0) {
217 ALOGE("%s: failed: could not open ion device\n", __func__);
218 } else {
219 mHalCamCtrl->mPreviewMemory.ion_info_fd[cnt].fd =
220 mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->fd;
221 if (ioctl(mHalCamCtrl->mPreviewMemory.main_ion_fd[cnt],
222 ION_IOC_IMPORT, &mHalCamCtrl->mPreviewMemory.ion_info_fd[cnt]) < 0)
223 ALOGE("ION import failed\n");
224 }
225#endif
226 mHalCamCtrl->mPreviewMemory.camera_memory[cnt] =
227 mHalCamCtrl->mGetMemory(mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->fd,
228 mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->size, 1, (void *)this);
229 ALOGV("%s: idx = %d, fd = %d, size = %d, offset = %d", __func__,
230 cnt, mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->fd,
231 mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->size,
232 mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->offset);
233 }
234
Shuzhen Wangf5e6f162013-04-16 16:08:11 -0700235 //Cancel min_undequeued_buffer buffers back to the window
236 for (int i = 0; i < numMinUndequeuedBufs; i ++) {
237 if( mHalCamCtrl->mPreviewMemory.local_flag[i] != BUFFER_NOT_OWNED) {
238 err = mPreviewWindow->cancel_buffer(mPreviewWindow, mHalCamCtrl->mPreviewMemory.buffer_handle[i]);
239 }
240 mHalCamCtrl->mPreviewMemory.local_flag[i] = BUFFER_NOT_OWNED;
241 }
Iliyan Malchev6d016452013-03-27 16:27:56 -0700242
243 memset(&mHalCamCtrl->mMetadata, 0, sizeof(mHalCamCtrl->mMetadata));
244 memset(mHalCamCtrl->mFace, 0, sizeof(mHalCamCtrl->mFace));
245
246 ALOGV(" %s : X ",__FUNCTION__);
247end:
248 //mDisplayLock.unlock();
249 mHalCamCtrl->mPreviewMemoryLock.unlock();
250
251 return ret;
252}
253
254status_t QCameraStream_preview::putBufferToSurface() {
255 int err = 0;
256 status_t ret = NO_ERROR;
257
258 ALOGV(" %s : E ", __FUNCTION__);
259
260 mHalCamCtrl->mPreviewMemoryLock.lock();
261 for (int cnt = 0; cnt < mHalCamCtrl->mPreviewMemory.buffer_count; cnt++) {
262 if (cnt < mHalCamCtrl->mPreviewMemory.buffer_count) {
263 if (NO_ERROR != mHalCamCtrl->sendUnMappingBuf(MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW, cnt, mCameraId,
264 CAM_SOCK_MSG_TYPE_FD_UNMAPPING)) {
265 ALOGE("%s: unmapping Preview Buffer", __func__);
266 }
267 if(mHalCamCtrl->isZSLMode()) {
268 if (NO_ERROR != mHalCamCtrl->sendUnMappingBuf(MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL, cnt, mCameraId,
269 CAM_SOCK_MSG_TYPE_FD_UNMAPPING)) {
270 ALOGE("%s: unmapping Thumbnail Buffer for ZSL", __func__);
271 }
272 }
273 }
274
275 mHalCamCtrl->mPreviewMemory.camera_memory[cnt]->release(mHalCamCtrl->mPreviewMemory.camera_memory[cnt]);
276#ifdef USE_ION
277 struct ion_handle_data ion_handle;
278 ion_handle.handle = mHalCamCtrl->mPreviewMemory.ion_info_fd[cnt].handle;
279 if (ioctl(mHalCamCtrl->mPreviewMemory.main_ion_fd[cnt], ION_IOC_FREE, &ion_handle)
280 < 0)
281 ALOGE("%s: ion free failed\n", __func__);
282 close(mHalCamCtrl->mPreviewMemory.main_ion_fd[cnt]);
283#endif
284 if (BUFFER_LOCKED == mHalCamCtrl->mPreviewMemory.local_flag[cnt]) {
285 ALOGV("%s: camera call genlock_unlock", __FUNCTION__);
286 if (GENLOCK_FAILURE == genlock_unlock_buffer((native_handle_t *)
287 (*(mHalCamCtrl->mPreviewMemory.buffer_handle[cnt])))) {
288 ALOGE("%s: genlock_unlock_buffer failed, handle =%p", __FUNCTION__, (*(mHalCamCtrl->mPreviewMemory.buffer_handle[cnt])));
289 continue;
290 //mHalCamCtrl->mPreviewMemoryLock.unlock();
291 //return -EINVAL;
292 } else {
293
294 ALOGV("%s: genlock_unlock_buffer, handle =%p", __FUNCTION__, (*(mHalCamCtrl->mPreviewMemory.buffer_handle[cnt])));
295 mHalCamCtrl->mPreviewMemory.local_flag[cnt] = BUFFER_UNLOCKED;
296 }
297 }
298 if( mHalCamCtrl->mPreviewMemory.local_flag[cnt] != BUFFER_NOT_OWNED) {
299 err = mPreviewWindow->cancel_buffer(mPreviewWindow, mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]);
300 ALOGV("%s: cancel_buffer: hdl =%p", __func__, (*mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]));
301 }
302 mHalCamCtrl->mPreviewMemory.local_flag[cnt] = BUFFER_NOT_OWNED;
303
304 ALOGV(" put buffer %d successfully", cnt);
305 }
306
307 if (mDisplayBuf.preview.buf.mp != NULL) {
308 delete[] mDisplayBuf.preview.buf.mp;
309 mDisplayBuf.preview.buf.mp = NULL;
310 }
311
312 mHalCamCtrl->mPreviewMemoryLock.unlock();
313 memset(&mHalCamCtrl->mPreviewMemory, 0, sizeof(mHalCamCtrl->mPreviewMemory));
314 ALOGV(" %s : X ",__FUNCTION__);
315 return NO_ERROR;
316}
317
318
319status_t QCameraStream_preview::getBufferNoDisplay( )
320{
321 int err = 0;
322 status_t ret = NO_ERROR;
323 int i, num_planes, frame_len, y_off, cbcr_off;
324 cam_ctrl_dimension_t dim;
325 uint32_t planes[VIDEO_MAX_PLANES];
326
327 ALOGV("%s : E ", __FUNCTION__);
328
329
330 ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION, &dim);
331 if(ret != NO_ERROR) {
332 ALOGE("%s: display format %d is not supported", __func__, dim.prev_format);
333 goto end;
334 }
335 mHalCamCtrl->mPreviewMemoryLock.lock();
336 mHalCamCtrl->mNoDispPreviewMemory.buffer_count = kPreviewBufferCount;
337 if(mHalCamCtrl->isZSLMode()) {
338 if(mHalCamCtrl->getZSLQueueDepth() > kPreviewBufferCount - 3)
339 mHalCamCtrl->mNoDispPreviewMemory.buffer_count =
340 mHalCamCtrl->getZSLQueueDepth() + 3;
341 }
342
343 num_planes = dim.display_frame_offset.num_planes;
344 for ( i = 0; i < num_planes; i++) {
345 planes[i] = dim.display_frame_offset.mp[i].len;
346 }
347
348 frame_len = dim.picture_frame_offset.frame_len;
349 y_off = dim.picture_frame_offset.mp[0].offset;
350 cbcr_off = dim.picture_frame_offset.mp[1].offset;
351 ALOGV("%s: main image: rotation = %d, yoff = %d, cbcroff = %d, size = %d, width = %d, height = %d",
352 __func__, dim.rotation, y_off, cbcr_off, frame_len,
353 dim.display_width, dim.display_height);
354 if (mHalCamCtrl->initHeapMem(&mHalCamCtrl->mNoDispPreviewMemory,
355 mHalCamCtrl->mNoDispPreviewMemory.buffer_count,
356 frame_len, y_off, cbcr_off, MSM_PMEM_MAINIMG,
357 NULL,NULL, num_planes, planes) < 0) {
358 ret = NO_MEMORY;
359 goto end;
360 };
361
362 memset(&mHalCamCtrl->mMetadata, 0, sizeof(mHalCamCtrl->mMetadata));
363 memset(mHalCamCtrl->mFace, 0, sizeof(mHalCamCtrl->mFace));
364
365 ALOGV(" %s : X ",__FUNCTION__);
366end:
367 //mDisplayLock.unlock();
368 mHalCamCtrl->mPreviewMemoryLock.unlock();
369
370 return NO_ERROR;
371}
372
373status_t QCameraStream_preview::freeBufferNoDisplay()
374{
375 int err = 0;
376 status_t ret = NO_ERROR;
377
378 ALOGV(" %s : E ", __FUNCTION__);
379
380 //mDisplayLock.lock();
381 mHalCamCtrl->mPreviewMemoryLock.lock();
382 for (int cnt = 0; cnt < mHalCamCtrl->mNoDispPreviewMemory.buffer_count; cnt++) {
383 if (cnt < mHalCamCtrl->mNoDispPreviewMemory.buffer_count) {
384 if (NO_ERROR != mHalCamCtrl->sendUnMappingBuf(MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW,
385 cnt, mCameraId, CAM_SOCK_MSG_TYPE_FD_UNMAPPING)) {
386 ALOGE("%s: sending data Msg Failed", __func__);
387 }
388 if(mHalCamCtrl->isZSLMode()) {
389 if (NO_ERROR != mHalCamCtrl->sendUnMappingBuf(MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL, cnt, mCameraId,
390 CAM_SOCK_MSG_TYPE_FD_UNMAPPING)) {
391 ALOGE("%s: Send socket msg to Unmap Failed", __func__);
392 }
393 }
394 }
395 }
396 mHalCamCtrl->releaseHeapMem(&mHalCamCtrl->mNoDispPreviewMemory);
397 memset(&mHalCamCtrl->mNoDispPreviewMemory, 0, sizeof(mHalCamCtrl->mNoDispPreviewMemory));
398 if (mDisplayBuf.preview.buf.mp != NULL) {
399 delete[] mDisplayBuf.preview.buf.mp;
400 mDisplayBuf.preview.buf.mp = NULL;
401 }
402
403 mHalCamCtrl->mPreviewMemoryLock.unlock();
404 ALOGV(" %s : X ",__FUNCTION__);
405 return NO_ERROR;
406}
407
408void QCameraStream_preview::notifyROIEvent(fd_roi_t roi)
409{
410 camera_memory_t *data = mHalCamCtrl->mGetMemory(-1, 1, 1, NULL);
411 switch (roi.type) {
412 case FD_ROI_TYPE_HEADER:
413 {
414 mDisplayLock.lock();
415 mNumFDRcvd = 0;
416 memset(mHalCamCtrl->mFace, 0, sizeof(mHalCamCtrl->mFace));
417 mHalCamCtrl->mMetadata.faces = mHalCamCtrl->mFace;
418 mHalCamCtrl->mMetadata.number_of_faces = roi.d.hdr.num_face_detected;
419 if(mHalCamCtrl->mMetadata.number_of_faces > MAX_ROI)
420 mHalCamCtrl->mMetadata.number_of_faces = MAX_ROI;
421 mDisplayLock.unlock();
422
423 if (mHalCamCtrl->mMetadata.number_of_faces == 0) {
424 // Clear previous faces
425 mHalCamCtrl->mCallbackLock.lock();
426 camera_data_callback pcb = mHalCamCtrl->mDataCb;
427 mHalCamCtrl->mCallbackLock.unlock();
428
429 if (pcb && (mHalCamCtrl->mMsgEnabled & CAMERA_MSG_PREVIEW_METADATA)){
430 ALOGV("%s: Face detection RIO callback", __func__);
431 pcb(CAMERA_MSG_PREVIEW_METADATA, data, 0, &mHalCamCtrl->mMetadata, mHalCamCtrl->mCallbackCookie);
432 }
433 }
434 }
435 break;
436 case FD_ROI_TYPE_DATA:
437 {
438 #if 1
439 mDisplayLock.lock();
440 int idx = roi.d.data.idx;
441 if (idx >= mHalCamCtrl->mMetadata.number_of_faces) {
442 mDisplayLock.unlock();
443 ALOGE("%s: idx %d out of boundary %d", __func__, idx, mHalCamCtrl->mMetadata.number_of_faces);
444 break;
445 }
446
447 mHalCamCtrl->mFace[idx].id = roi.d.data.face.id;
448 mHalCamCtrl->mFace[idx].score = roi.d.data.face.score;
449
450 // top
451 mHalCamCtrl->mFace[idx].rect[0] =
452 roi.d.data.face.face_boundary.x*2000/mHalCamCtrl->mDimension.display_width - 1000;
453 //right
454 mHalCamCtrl->mFace[idx].rect[1] =
455 roi.d.data.face.face_boundary.y*2000/mHalCamCtrl->mDimension.display_height - 1000;
456 //bottom
457 mHalCamCtrl->mFace[idx].rect[2] = mHalCamCtrl->mFace[idx].rect[0] +
458 roi.d.data.face.face_boundary.dx*2000/mHalCamCtrl->mDimension.display_width;
459 //left
460 mHalCamCtrl->mFace[idx].rect[3] = mHalCamCtrl->mFace[idx].rect[1] +
461 roi.d.data.face.face_boundary.dy*2000/mHalCamCtrl->mDimension.display_height;
462
463 // Center of left eye
464 mHalCamCtrl->mFace[idx].left_eye[0] =
465 roi.d.data.face.left_eye_center[0]*2000/mHalCamCtrl->mDimension.display_width - 1000;
466 mHalCamCtrl->mFace[idx].left_eye[1] =
467 roi.d.data.face.left_eye_center[1]*2000/mHalCamCtrl->mDimension.display_height - 1000;
468
469 // Center of right eye
470 mHalCamCtrl->mFace[idx].right_eye[0] =
471 roi.d.data.face.right_eye_center[0]*2000/mHalCamCtrl->mDimension.display_width - 1000;
472 mHalCamCtrl->mFace[idx].right_eye[1] =
473 roi.d.data.face.right_eye_center[1]*2000/mHalCamCtrl->mDimension.display_height - 1000;
474#if 0
475 // Center of mouth
476 mHalCamCtrl->mFace[idx].mouth[0] =
477 roi.d.data.face.mouth_center[0]*2000/mHalCamCtrl->mDimension.display_width - 1000;
478 mHalCamCtrl->mFace[idx].mouth[1] =
479 roi.d.data.face.mouth_center[1]*2000/mHalCamCtrl->mDimension.display_height - 1000;
480
481 mHalCamCtrl->mFace[idx].smile_degree = roi.d.data.face.smile_degree;
482 mHalCamCtrl->mFace[idx].smile_score = roi.d.data.face.smile_confidence;
483 mHalCamCtrl->mFace[idx].blink_detected = roi.d.data.face.blink_detected;
484 mHalCamCtrl->mFace[idx].face_recognised = roi.d.data.face.is_face_recognised;
485 mHalCamCtrl->mFace[idx].gaze_angle = roi.d.data.face.gaze_angle;
486
487 /* newly added */
488 // upscale by 2 to recover from demaen downscaling
489 mHalCamCtrl->mFace[idx].updown_dir = roi.d.data.face.updown_dir*2;
490 mHalCamCtrl->mFace[idx].leftright_dir = roi.d.data.face.leftright_dir*2;
491 mHalCamCtrl->mFace[idx].roll_dir = roi.d.data.face.roll_dir*2;
492
493 mHalCamCtrl->mFace[idx].leye_blink = roi.d.data.face.left_blink;
494 mHalCamCtrl->mFace[idx].reye_blink = roi.d.data.face.right_blink;
495 mHalCamCtrl->mFace[idx].left_right_gaze = roi.d.data.face.left_right_gaze;
496 mHalCamCtrl->mFace[idx].top_bottom_gaze = roi.d.data.face.top_bottom_gaze;
497 ALOGE("%s: Face(%d, %d, %d, %d), leftEye(%d, %d), rightEye(%d, %d), mouth(%d, %d), smile(%d, %d), face_recg(%d)", __func__,
498 mHalCamCtrl->mFace[idx].rect[0], mHalCamCtrl->mFace[idx].rect[1],
499 mHalCamCtrl->mFace[idx].rect[2], mHalCamCtrl->mFace[idx].rect[3],
500 mHalCamCtrl->mFace[idx].left_eye[0], mHalCamCtrl->mFace[idx].left_eye[1],
501 mHalCamCtrl->mFace[idx].right_eye[0], mHalCamCtrl->mFace[idx].right_eye[1],
502 mHalCamCtrl->mFace[idx].mouth[0], mHalCamCtrl->mFace[idx].mouth[1],
503 mHalCamCtrl->mFace[idx].smile_degree, mHalCamCtrl->mFace[idx].smile_score,
504 mHalCamCtrl->mFace[idx].face_recognised);
505 ALOGE("%s: gaze(%d, %d, %d), updown(%d), leftright(%d), roll(%d), blink(%d, %d, %d)", __func__,
506 mHalCamCtrl->mFace[idx].gaze_angle, mHalCamCtrl->mFace[idx].left_right_gaze,
507 mHalCamCtrl->mFace[idx].top_bottom_gaze, mHalCamCtrl->mFace[idx].updown_dir,
508 mHalCamCtrl->mFace[idx].leftright_dir, mHalCamCtrl->mFace[idx].roll_dir,
509 mHalCamCtrl->mFace[idx].blink_detected,
510 mHalCamCtrl->mFace[idx].leye_blink, mHalCamCtrl->mFace[idx].reye_blink);
511#endif
512 mNumFDRcvd++;
513 mDisplayLock.unlock();
514
515 if (mNumFDRcvd == mHalCamCtrl->mMetadata.number_of_faces) {
516 mHalCamCtrl->mCallbackLock.lock();
517 camera_data_callback pcb = mHalCamCtrl->mDataCb;
518 mHalCamCtrl->mCallbackLock.unlock();
519
520 if (pcb && (mHalCamCtrl->mMsgEnabled & CAMERA_MSG_PREVIEW_METADATA)){
521 ALOGV("%s: Face detection RIO callback with %d faces detected (score=%d)", __func__, mNumFDRcvd, mHalCamCtrl->mFace[idx].score);
522 pcb(CAMERA_MSG_PREVIEW_METADATA, data, 0, &mHalCamCtrl->mMetadata, mHalCamCtrl->mCallbackCookie);
523 }
524 }
525 #endif
526 }
527 break;
528 }
529 if(NULL != data) data->release(data);
530}
531
532status_t QCameraStream_preview::initDisplayBuffers()
533{
534 status_t ret = NO_ERROR;
535 int width = 0; /* width of channel */
536 int height = 0; /* height of channel */
537 uint32_t frame_len = 0; /* frame planner length */
538 int buffer_num = 4, i; /* number of buffers for display */
539 const char *pmem_region;
540 uint8_t num_planes = 0;
541 uint32_t planes[VIDEO_MAX_PLANES];
542 void *vaddr = NULL;
543 cam_ctrl_dimension_t dim;
544
545 ALOGV("%s:BEGIN",__func__);
546 memset(&mHalCamCtrl->mMetadata, 0, sizeof(camera_frame_metadata_t));
547 mHalCamCtrl->mPreviewMemoryLock.lock();
548 memset(&mHalCamCtrl->mPreviewMemory, 0, sizeof(mHalCamCtrl->mPreviewMemory));
549 mHalCamCtrl->mPreviewMemoryLock.unlock();
550 memset(&mNotifyBuffer, 0, sizeof(mNotifyBuffer));
551
552/* get preview size, by qury mm_camera*/
553 memset(&dim, 0, sizeof(cam_ctrl_dimension_t));
554
555 memset(&(this->mDisplayStreamBuf),0, sizeof(this->mDisplayStreamBuf));
556
557 ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION, &dim);
558 if (MM_CAMERA_OK != ret) {
559 ALOGE("%s: error - can't get camera dimension!", __func__);
560 ALOGV("%s: X", __func__);
561 return BAD_VALUE;
562 }else {
563 width = dim.display_width,
564 height = dim.display_height;
565 }
566
567 ret = getBufferFromSurface();
568 if(ret != NO_ERROR) {
569 ALOGE("%s: cannot get memory from surface texture client, ret = %d", __func__, ret);
570 return ret;
571 }
572
573 /* set 4 buffers for display */
574 mHalCamCtrl->mPreviewMemoryLock.lock();
575 memset(&mDisplayStreamBuf, 0, sizeof(mDisplayStreamBuf));
576 this->mDisplayStreamBuf.num = mHalCamCtrl->mPreviewMemory.buffer_count;
577 this->myMode=myMode; /*Need to assign this in constructor after translating from mask*/
578 num_planes = dim.display_frame_offset.num_planes;
579 for(i =0; i< num_planes; i++) {
580 planes[i] = dim.display_frame_offset.mp[i].len;
581 }
582 this->mDisplayStreamBuf.frame_len = dim.display_frame_offset.frame_len;
583
584 memset(&mDisplayBuf, 0, sizeof(mDisplayBuf));
585 mDisplayBuf.preview.buf.mp = new mm_camera_mp_buf_t[mDisplayStreamBuf.num];
586 if (!mDisplayBuf.preview.buf.mp) {
587 ALOGE("%s Error allocating memory for mplanar struct ", __func__);
588 ret = NO_MEMORY;
589 goto error;
590 }
591 memset(mDisplayBuf.preview.buf.mp, 0,
592 mDisplayStreamBuf.num * sizeof(mm_camera_mp_buf_t));
593
594 /*allocate memory for the buffers*/
595 for(int i = 0; i < mDisplayStreamBuf.num; i++){
596 if (mHalCamCtrl->mPreviewMemory.private_buffer_handle[i] == NULL)
597 continue;
598 mDisplayStreamBuf.frame[i].fd = mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->fd;
599 mDisplayStreamBuf.frame[i].cbcr_off = planes[0];
600 mDisplayStreamBuf.frame[i].y_off = 0;
601 mDisplayStreamBuf.frame[i].path = OUTPUT_TYPE_P;
602 mHalCamCtrl->mPreviewMemory.addr_offset[i] =
603 mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->offset;
604 mDisplayStreamBuf.frame[i].buffer =
605 (long unsigned int)mHalCamCtrl->mPreviewMemory.camera_memory[i]->data;
606 mDisplayStreamBuf.frame[i].ion_alloc.len = mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->size;
607 mDisplayStreamBuf.frame[i].ion_dev_fd = mHalCamCtrl->mPreviewMemory.main_ion_fd[i];
608 mDisplayStreamBuf.frame[i].fd_data = mHalCamCtrl->mPreviewMemory.ion_info_fd[i];
609
610 ALOGV("%s: idx = %d, fd = %d, size = %d, cbcr_offset = %d, y_offset = %d, "
611 "offset = %d, vaddr = 0x%x", __func__, i, mDisplayStreamBuf.frame[i].fd,
612 mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->size,
613 mDisplayStreamBuf.frame[i].cbcr_off, mDisplayStreamBuf.frame[i].y_off,
614 mHalCamCtrl->mPreviewMemory.addr_offset[i],
615 (uint32_t)mDisplayStreamBuf.frame[i].buffer);
616
617 ret = mHalCamCtrl->sendMappingBuf(
618 MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW,
619 i,
620 mDisplayStreamBuf.frame[i].fd,
621 mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->size,
622 mCameraId, CAM_SOCK_MSG_TYPE_FD_MAPPING);
623 if (NO_ERROR != ret) {
624 ALOGE("%s: sending mapping data Msg Failed", __func__);
625 goto error;
626 }
627
628 if(mHalCamCtrl->isZSLMode()) {
629 ret = mHalCamCtrl->sendMappingBuf(
630 MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL,
631 i,
632 mDisplayStreamBuf.frame[i].fd,
633 mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->size,
634 mCameraId, CAM_SOCK_MSG_TYPE_FD_MAPPING);
635 if (NO_ERROR != ret) {
636 ALOGE("%s: Send socket msg to map Failed", __func__);
637 goto error;
638 }
639 }
640 mDisplayBuf.preview.buf.mp[i].frame = mDisplayStreamBuf.frame[i];
641 mDisplayBuf.preview.buf.mp[i].frame_offset = mHalCamCtrl->mPreviewMemory.addr_offset[i];
642 mDisplayBuf.preview.buf.mp[i].num_planes = num_planes;
643
644 /* Plane 0 needs to be set seperately. Set other planes
645 * in a loop. */
646 mDisplayBuf.preview.buf.mp[i].planes[0].length = planes[0];
647 mDisplayBuf.preview.buf.mp[i].planes[0].m.userptr = mDisplayStreamBuf.frame[i].fd;
648 mDisplayBuf.preview.buf.mp[i].planes[0].data_offset = 0;
649 mDisplayBuf.preview.buf.mp[i].planes[0].reserved[0] =
650 mDisplayBuf.preview.buf.mp[i].frame_offset;
651 for (int j = 1; j < num_planes; j++) {
652 mDisplayBuf.preview.buf.mp[i].planes[j].length = planes[j];
653 mDisplayBuf.preview.buf.mp[i].planes[j].m.userptr =
654 mDisplayStreamBuf.frame[i].fd;
655 mDisplayBuf.preview.buf.mp[i].planes[j].data_offset = 0;
656 mDisplayBuf.preview.buf.mp[i].planes[j].reserved[0] =
657 mDisplayBuf.preview.buf.mp[i].planes[j-1].reserved[0] +
658 mDisplayBuf.preview.buf.mp[i].planes[j-1].length;
659 }
660
661 for (int j = 0; j < num_planes; j++)
662 ALOGV("Planes: %d length: %d userptr: %lu offset: %d\n", j,
663 mDisplayBuf.preview.buf.mp[i].planes[j].length,
664 mDisplayBuf.preview.buf.mp[i].planes[j].m.userptr,
665 mDisplayBuf.preview.buf.mp[i].planes[j].reserved[0]);
666 }/*end of for loop*/
667
668 /* register the streaming buffers for the channel*/
669 mDisplayBuf.ch_type = MM_CAMERA_CH_PREVIEW;
670 mDisplayBuf.preview.num = mDisplayStreamBuf.num;
671 mHalCamCtrl->mPreviewMemoryLock.unlock();
672 ALOGV("%s:END",__func__);
673 return NO_ERROR;
674
675error:
676 mHalCamCtrl->mPreviewMemoryLock.unlock();
677 putBufferToSurface();
678
679 ALOGV("%s: X", __func__);
680 return ret;
681}
682
683status_t QCameraStream_preview::initPreviewOnlyBuffers()
684{
685 status_t ret = NO_ERROR;
686 int width = 0; /* width of channel */
687 int height = 0; /* height of channel */
688 uint32_t frame_len = 0; /* frame planner length */
689 int buffer_num = 4; /* number of buffers for display */
690 const char *pmem_region;
691 uint8_t num_planes = 0;
692 uint32_t planes[VIDEO_MAX_PLANES];
693
694 cam_ctrl_dimension_t dim;
695
696 ALOGV("%s:BEGIN",__func__);
697 memset(&mHalCamCtrl->mMetadata, 0, sizeof(camera_frame_metadata_t));
698 mHalCamCtrl->mPreviewMemoryLock.lock();
699 memset(&mHalCamCtrl->mNoDispPreviewMemory, 0, sizeof(mHalCamCtrl->mNoDispPreviewMemory));
700 mHalCamCtrl->mPreviewMemoryLock.unlock();
701 memset(&mNotifyBuffer, 0, sizeof(mNotifyBuffer));
702
703/* get preview size, by qury mm_camera*/
704 memset(&dim, 0, sizeof(cam_ctrl_dimension_t));
705 ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION, &dim);
706 if (MM_CAMERA_OK != ret) {
707 ALOGE("%s: error - can't get camera dimension!", __func__);
708 ALOGV("%s: X", __func__);
709 return BAD_VALUE;
710 }else {
711 width = dim.display_width;
712 height = dim.display_height;
713 }
714
715 ret = getBufferNoDisplay( );
716 if(ret != NO_ERROR) {
717 ALOGE("%s: cannot get memory from surface texture client, ret = %d", __func__, ret);
718 return ret;
719 }
720
721 /* set 4 buffers for display */
722 memset(&mDisplayStreamBuf, 0, sizeof(mDisplayStreamBuf));
723 mHalCamCtrl->mPreviewMemoryLock.lock();
724 this->mDisplayStreamBuf.num = mHalCamCtrl->mNoDispPreviewMemory.buffer_count;
725 this->myMode=myMode; /*Need to assign this in constructor after translating from mask*/
726 num_planes = dim.display_frame_offset.num_planes;
727 for (int i = 0; i < num_planes; i++) {
728 planes[i] = dim.display_frame_offset.mp[i].len;
729 }
730 this->mDisplayStreamBuf.frame_len = dim.display_frame_offset.frame_len;
731
732 memset(&mDisplayBuf, 0, sizeof(mDisplayBuf));
733 mDisplayBuf.preview.buf.mp = new mm_camera_mp_buf_t[mDisplayStreamBuf.num];
734 if (!mDisplayBuf.preview.buf.mp) {
735 ALOGE("%s Error allocating memory for mplanar struct ", __func__);
736 }
737 memset(mDisplayBuf.preview.buf.mp, 0,
738 mDisplayStreamBuf.num * sizeof(mm_camera_mp_buf_t));
739
740 /*allocate memory for the buffers*/
741 void *vaddr = NULL;
742 for(int i = 0; i < mDisplayStreamBuf.num; i++){
743 if (mHalCamCtrl->mNoDispPreviewMemory.camera_memory[i] == NULL)
744 continue;
745 mDisplayStreamBuf.frame[i].fd = mHalCamCtrl->mNoDispPreviewMemory.fd[i];
746 mDisplayStreamBuf.frame[i].cbcr_off = planes[0];
747 mDisplayStreamBuf.frame[i].y_off = 0;
748 mDisplayStreamBuf.frame[i].path = OUTPUT_TYPE_P;
749 mDisplayStreamBuf.frame[i].buffer =
750 (long unsigned int)mHalCamCtrl->mNoDispPreviewMemory.camera_memory[i]->data;
751 mDisplayStreamBuf.frame[i].ion_dev_fd = mHalCamCtrl->mNoDispPreviewMemory.main_ion_fd[i];
752 mDisplayStreamBuf.frame[i].fd_data = mHalCamCtrl->mNoDispPreviewMemory.ion_info_fd[i];
753
754 ALOGV("%s: idx = %d, fd = %d, size = %d, cbcr_offset = %d, y_offset = %d, "
755 "vaddr = 0x%x", __func__, i, mDisplayStreamBuf.frame[i].fd,
756 frame_len,
757 mDisplayStreamBuf.frame[i].cbcr_off, mDisplayStreamBuf.frame[i].y_off,
758 (uint32_t)mDisplayStreamBuf.frame[i].buffer);
759
760 if (NO_ERROR != mHalCamCtrl->sendMappingBuf(
761 MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW,
762 i,
763 mDisplayStreamBuf.frame[i].fd,
764 mHalCamCtrl->mNoDispPreviewMemory.size,
765 mCameraId, CAM_SOCK_MSG_TYPE_FD_MAPPING)) {
766 ALOGE("%s: sending mapping data Msg Failed", __func__);
767 }
768
769 if(mHalCamCtrl->isZSLMode()) {
770 if (NO_ERROR != mHalCamCtrl->sendMappingBuf(
771 MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL,
772 i,
773 mDisplayStreamBuf.frame[i].fd,
774 mHalCamCtrl->mNoDispPreviewMemory.size,
775 mCameraId, CAM_SOCK_MSG_TYPE_FD_MAPPING)) {
776 ALOGE("%s: sending mapping data Msg Failed", __func__);
777 }
778 }
779 mDisplayBuf.preview.buf.mp[i].frame = mDisplayStreamBuf.frame[i];
780 mDisplayBuf.preview.buf.mp[i].frame_offset = mDisplayStreamBuf.frame[i].y_off;
781 mDisplayBuf.preview.buf.mp[i].num_planes = num_planes;
782
783 /* Plane 0 needs to be set seperately. Set other planes
784 * in a loop. */
785 mDisplayBuf.preview.buf.mp[i].planes[0].length = planes[0];
786 mDisplayBuf.preview.buf.mp[i].planes[0].m.userptr = mDisplayStreamBuf.frame[i].fd;
787 mDisplayBuf.preview.buf.mp[i].planes[0].data_offset = 0;
788 mDisplayBuf.preview.buf.mp[i].planes[0].reserved[0] =
789 mDisplayBuf.preview.buf.mp[i].frame_offset;
790 for (int j = 1; j < num_planes; j++) {
791 mDisplayBuf.preview.buf.mp[i].planes[j].length = planes[j];
792 mDisplayBuf.preview.buf.mp[i].planes[j].m.userptr =
793 mDisplayStreamBuf.frame[i].fd;
794 mDisplayBuf.preview.buf.mp[i].planes[j].data_offset = 0;
795 mDisplayBuf.preview.buf.mp[i].planes[j].reserved[0] =
796 mDisplayBuf.preview.buf.mp[i].planes[j-1].reserved[0] +
797 mDisplayBuf.preview.buf.mp[i].planes[j-1].length;
798 }
799
800 for (int j = 0; j < num_planes; j++)
801 ALOGV("Planes: %d length: %d userptr: %lu offset: %d\n", j,
802 mDisplayBuf.preview.buf.mp[i].planes[j].length,
803 mDisplayBuf.preview.buf.mp[i].planes[j].m.userptr,
804 mDisplayBuf.preview.buf.mp[i].planes[j].reserved[0]);
805 }/*end of for loop*/
806
807 /* register the streaming buffers for the channel*/
808 mDisplayBuf.ch_type = MM_CAMERA_CH_PREVIEW;
809 mDisplayBuf.preview.num = mDisplayStreamBuf.num;
810 mHalCamCtrl->mPreviewMemoryLock.unlock();
811 ALOGV("%s:END",__func__);
812 return NO_ERROR;
813
814end:
815 if (MM_CAMERA_OK == ret ) {
816 ALOGV("%s: X - NO_ERROR ", __func__);
817 return NO_ERROR;
818 }
819
820 ALOGV("%s: out of memory clean up", __func__);
821 /* release the allocated memory */
822
823 ALOGV("%s: X - BAD_VALUE ", __func__);
824 return BAD_VALUE;
825}
826
827
828void QCameraStream_preview::dumpFrameToFile(struct msm_frame* newFrame)
829{
830#if 0
831 int32_t enabled = 0;
832 int frm_num;
833 uint32_t skip_mode;
834 char value[PROPERTY_VALUE_MAX];
835 char buf[32];
836 int w, h;
837 static int count = 0;
838 cam_ctrl_dimension_t dim;
839 int file_fd;
840 int rc = 0;
841 int len;
842 unsigned long addr;
843 unsigned long * tmp = (unsigned long *)newFrame->buffer;
844 addr = *tmp;
845 status_t ret = cam_config_get_parm(mHalCamCtrl->mCameraId,
846 MM_CAMERA_PARM_DIMENSION, &dim);
847
848 w = dim.display_width;
849 h = dim.display_height;
850 len = (w * h)*3/2;
851 count++;
852 if(count < 100) {
853 snprintf(buf, sizeof(buf), "/data/mzhu%d.yuv", count);
854 file_fd = open(buf, O_RDWR | O_CREAT, 0777);
855
856 rc = write(file_fd, (const void *)addr, len);
857 ALOGV("%s: file='%s', vaddr_old=0x%x, addr_map = 0x%p, len = %d, rc = %d",
858 __func__, buf, (uint32_t)newFrame->buffer, (void *)addr, len, rc);
859 close(file_fd);
860 ALOGV("%s: dump %s, rc = %d, len = %d", __func__, buf, rc, len);
861 }
862#endif
863}
864
865status_t QCameraStream_preview::processPreviewFrameWithDisplay(
866 mm_camera_ch_data_buf_t *frame)
867{
868 ALOGV("%s",__func__);
869 int err = 0;
870 int msgType = 0;
871 int i;
872 camera_memory_t *data = NULL;
873 camera_frame_metadata_t *metadata = NULL;
874
875 Mutex::Autolock lock(mStopCallbackLock);
876 if(!mActive) {
877 ALOGV("Preview Stopped. Returning callback");
878 return NO_ERROR;
879 }
880
881 if(mHalCamCtrl==NULL) {
882 ALOGE("%s: X: HAL control object not set",__func__);
883 /*Call buf done*/
884 return BAD_VALUE;
885 }
886
887 if(mHalCamCtrl->mPauseFramedispatch) {
888 if(MM_CAMERA_OK != cam_evt_buf_done(mCameraId, frame)) {
889 ALOGE("BUF DONE FAILED for the recylce buffer");
890 }
891 return NO_ERROR;
892 }
893 mHalCamCtrl->mCallbackLock.lock();
894 camera_data_timestamp_callback rcb = mHalCamCtrl->mDataCbTimestamp;
895 void *rdata = mHalCamCtrl->mCallbackCookie;
896 mHalCamCtrl->mCallbackLock.unlock();
897 nsecs_t timeStamp = seconds_to_nanoseconds(frame->def.frame->ts.tv_sec) ;
898 timeStamp += frame->def.frame->ts.tv_nsec;
899
900 if(mFirstFrameRcvd == false) {
901 mm_camera_util_profile("HAL: First preview frame received");
902 mFirstFrameRcvd = true;
903 }
904
905 if (UNLIKELY(mHalCamCtrl->mDebugFps)) {
906 mHalCamCtrl->debugShowPreviewFPS();
907 }
908 //dumpFrameToFile(frame->def.frame);
909 mHalCamCtrl->dumpFrameToFile(frame->def.frame, HAL_DUMP_FRM_PREVIEW);
910
911 mHalCamCtrl->mPreviewMemoryLock.lock();
912 mNotifyBuffer[frame->def.idx] = *frame;
913
914 ALOGV("Enqueue buf handle %p\n",
915 mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]);
916 ALOGV("%s: camera call genlock_unlock", __FUNCTION__);
917
918 if (BUFFER_LOCKED == mHalCamCtrl->mPreviewMemory.local_flag[frame->def.idx]) {
919 ALOGV("%s: genlock_unlock_buffer hdl =%p", __FUNCTION__, (*mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]));
920 if (GENLOCK_FAILURE == genlock_unlock_buffer((native_handle_t*)
921 (*mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]))) {
922 ALOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
923 //mHalCamCtrl->mPreviewMemoryLock.unlock();
924 //return -EINVAL;
925 } else {
926 mHalCamCtrl->mPreviewMemory.local_flag[frame->def.idx] = BUFFER_UNLOCKED;
927 }
928 } else {
929 ALOGE("%s: buffer to be enqueued is not locked", __FUNCTION__);
Shuzhen Wangf5e6f162013-04-16 16:08:11 -0700930 mHalCamCtrl->mPreviewMemoryLock.unlock();
931 return -EINVAL;
Iliyan Malchev6d016452013-03-27 16:27:56 -0700932 }
933
934#ifdef USE_ION
935 struct ion_flush_data cache_inv_data;
936 int ion_fd;
937 ion_fd = frame->def.frame->ion_dev_fd;
938 cache_inv_data.vaddr = (void *)frame->def.frame->buffer;
939 cache_inv_data.fd = frame->def.frame->fd;
940 cache_inv_data.handle = frame->def.frame->fd_data.handle;
941 cache_inv_data.length = frame->def.frame->ion_alloc.len;
942
943 if (mHalCamCtrl->cache_ops(ion_fd, &cache_inv_data,
944 ION_IOC_CLEAN_INV_CACHES) < 0)
945 ALOGE("%s: Cache clean for Preview buffer %p fd = %d failed", __func__,
946 cache_inv_data.vaddr, cache_inv_data.fd);
947#endif
948
949 if(mHFRFrameSkip == 1)
950 {
951 const char *str = mHalCamCtrl->mParameters.get(
952 QCameraParameters::KEY_VIDEO_HIGH_FRAME_RATE);
953 if(str != NULL){
954 int is_hfr_off = 0;
955 mHFRFrameCnt++;
956 if(!strcmp(str, QCameraParameters::VIDEO_HFR_OFF)) {
957 is_hfr_off = 1;
958 err = this->mPreviewWindow->enqueue_buffer(this->mPreviewWindow,
959 (buffer_handle_t *)mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]);
960 } else if (!strcmp(str, QCameraParameters::VIDEO_HFR_2X)) {
961 mHFRFrameCnt %= 2;
962 } else if (!strcmp(str, QCameraParameters::VIDEO_HFR_3X)) {
963 mHFRFrameCnt %= 3;
964 } else if (!strcmp(str, QCameraParameters::VIDEO_HFR_4X)) {
965 mHFRFrameCnt %= 4;
966 }
967 if(mHFRFrameCnt == 0)
968 err = this->mPreviewWindow->enqueue_buffer(this->mPreviewWindow,
969 (buffer_handle_t *)mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]);
970 else if(!is_hfr_off)
971 err = this->mPreviewWindow->cancel_buffer(this->mPreviewWindow,
972 (buffer_handle_t *)mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]);
973 } else
974 err = this->mPreviewWindow->enqueue_buffer(this->mPreviewWindow,
975 (buffer_handle_t *)mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]);
976 } else {
977 err = this->mPreviewWindow->enqueue_buffer(this->mPreviewWindow,
978 (buffer_handle_t *)mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]);
979 }
980 if(err != 0) {
981 ALOGE("%s: enqueue_buffer failed, err = %d", __func__, err);
982 } else {
983 ALOGV("%s: enqueue_buffer hdl=%p", __func__, *mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]);
984 mHalCamCtrl->mPreviewMemory.local_flag[frame->def.idx] = BUFFER_NOT_OWNED;
985 }
986 buffer_handle_t *buffer_handle = NULL;
987 int tmp_stride = 0;
988 err = this->mPreviewWindow->dequeue_buffer(this->mPreviewWindow,
989 &buffer_handle, &tmp_stride);
990 if (err == NO_ERROR && buffer_handle != NULL) {
991
992 ALOGV("%s: dequed buf hdl =%p", __func__, *buffer_handle);
993 for(i = 0; i < mHalCamCtrl->mPreviewMemory.buffer_count; i++) {
994 if(mHalCamCtrl->mPreviewMemory.buffer_handle[i] == buffer_handle) {
995 mHalCamCtrl->mPreviewMemory.local_flag[i] = BUFFER_UNLOCKED;
996 break;
997 }
998 }
999 if (i < mHalCamCtrl->mPreviewMemory.buffer_count ) {
1000 err = this->mPreviewWindow->lock_buffer(this->mPreviewWindow, buffer_handle);
1001 ALOGV("%s: camera call genlock_lock: hdl =%p", __FUNCTION__, *buffer_handle);
1002 if (GENLOCK_FAILURE == genlock_lock_buffer((native_handle_t*)(*buffer_handle), GENLOCK_WRITE_LOCK,
1003 GENLOCK_MAX_TIMEOUT)) {
1004 ALOGE("%s: genlock_lock_buffer(WRITE) failed", __FUNCTION__);
1005 //mHalCamCtrl->mPreviewMemoryLock.unlock();
1006 // return -EINVAL;
1007 } else {
1008 mHalCamCtrl->mPreviewMemory.local_flag[i] = BUFFER_LOCKED;
1009
1010 if(MM_CAMERA_OK != cam_evt_buf_done(mCameraId, &mNotifyBuffer[i])) {
1011 ALOGE("BUF DONE FAILED");
1012 }
1013 }
1014 }
1015 } else
1016 ALOGV("%s: error in dequeue_buffer, enqueue_buffer idx = %d, no free buffer now", __func__, frame->def.idx);
1017
1018 /* Save the last displayed frame. We'll be using it to fill the gap between
1019 when preview stops and postview start during snapshot.*/
1020 mLastQueuedFrame = &(mDisplayStreamBuf.frame[frame->def.idx]);
1021 mHalCamCtrl->mPreviewMemoryLock.unlock();
1022
1023 mHalCamCtrl->mCallbackLock.lock();
1024 camera_data_callback pcb = mHalCamCtrl->mDataCb;
1025 mHalCamCtrl->mCallbackLock.unlock();
1026 ALOGV("Message enabled = 0x%x", mHalCamCtrl->mMsgEnabled);
1027
1028 camera_memory_t *previewMem = NULL;
1029
1030 if (pcb != NULL) {
1031 ALOGV("%s: mMsgEnabled =0x%x, preview format =%d", __func__,
1032 mHalCamCtrl->mMsgEnabled, mHalCamCtrl->mPreviewFormat);
1033 //Sending preview callback if corresponding Msgs are enabled
1034 if(mHalCamCtrl->mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME) {
1035 ALOGV("%s: PCB callback enabled", __func__);
1036 msgType |= CAMERA_MSG_PREVIEW_FRAME;
1037 int previewBufSize;
1038 /* The preview buffer size sent back in the callback should be (width*height*bytes_per_pixel)
1039 * As all preview formats we support, use 12 bits per pixel, buffer size = previewWidth * previewHeight * 3/2.
1040 * We need to put a check if some other formats are supported in future. (punits) */
1041 if ((mHalCamCtrl->mPreviewFormat == CAMERA_YUV_420_NV21) || (mHalCamCtrl->mPreviewFormat == CAMERA_YUV_420_NV12) ||
1042 (mHalCamCtrl->mPreviewFormat == CAMERA_YUV_420_YV12))
1043 {
1044 if (mHalCamCtrl->mPreviewFormat == CAMERA_YUV_420_YV12) {
1045 previewBufSize = ((mHalCamCtrl->mPreviewWidth+15)/16) *16* mHalCamCtrl->mPreviewHeight +
1046 ((mHalCamCtrl->mPreviewWidth/2+15)/16)*16* mHalCamCtrl->mPreviewHeight;
1047 } else {
1048 previewBufSize = mHalCamCtrl->mPreviewWidth * mHalCamCtrl->mPreviewHeight * 3/2;
1049 }
1050 if(previewBufSize != mHalCamCtrl->mPreviewMemory.private_buffer_handle[frame->def.idx]->size) {
1051 previewMem = mHalCamCtrl->mGetMemory(mHalCamCtrl->mPreviewMemory.private_buffer_handle[frame->def.idx]->fd,
1052 previewBufSize, 1, mHalCamCtrl->mCallbackCookie);
1053 if (!previewMem || !previewMem->data) {
1054 ALOGE("%s: mGetMemory failed.\n", __func__);
1055 } else {
1056 data = previewMem;
1057 }
1058 } else
1059 data = mHalCamCtrl->mPreviewMemory.camera_memory[frame->def.idx];
1060 } else {
1061 data = mHalCamCtrl->mPreviewMemory.camera_memory[frame->def.idx];
1062 ALOGE("Invalid preview format, buffer size in preview callback may be wrong.");
1063 }
1064 } else {
1065 data = NULL;
1066 }
1067 if(msgType) {
1068 mStopCallbackLock.unlock();
1069 if(mActive)
1070 pcb(msgType, data, 0, metadata, mHalCamCtrl->mCallbackCookie);
1071 if (previewMem)
1072 previewMem->release(previewMem);
1073 mStopCallbackLock.lock();
1074 }
1075 ALOGV("end of cb");
1076 } else {
1077 ALOGV("%s PCB is not enabled", __func__);
1078 }
1079 if(rcb != NULL && mVFEOutputs == 1)
1080 {
1081 int flagwait = 1;
1082 if(mHalCamCtrl->mStartRecording == true &&
1083 ( mHalCamCtrl->mMsgEnabled & CAMERA_MSG_VIDEO_FRAME))
1084 {
1085 if (mHalCamCtrl->mStoreMetaDataInFrame)
1086 {
1087 if(mHalCamCtrl->mRecordingMemory.metadata_memory[frame->def.idx])
1088 {
1089 flagwait = 1;
1090 mStopCallbackLock.unlock();
1091 rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME,
1092 mHalCamCtrl->mRecordingMemory.metadata_memory[frame->def.idx],
1093 0, mHalCamCtrl->mCallbackCookie);
1094 mStopCallbackLock.lock();
1095 }else
1096 flagwait = 0;
1097 }
1098 else
1099 {
1100 mStopCallbackLock.unlock();
1101 rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME,
1102 mHalCamCtrl->mPreviewMemory.camera_memory[frame->def.idx],
1103 0, mHalCamCtrl->mCallbackCookie);
1104 mStopCallbackLock.lock();
1105 }
1106
1107 if(flagwait){
1108 Mutex::Autolock rLock(&mHalCamCtrl->mRecordFrameLock);
1109 if (mHalCamCtrl->mReleasedRecordingFrame != true) {
1110 mHalCamCtrl->mRecordWait.wait(mHalCamCtrl->mRecordFrameLock);
1111 }
1112 mHalCamCtrl->mReleasedRecordingFrame = false;
1113 }
1114 }
1115 }
1116 /* Save the last displayed frame. We'll be using it to fill the gap between
1117 when preview stops and postview start during snapshot.*/
1118 //mLastQueuedFrame = frame->def.frame;
1119/*
1120 if(MM_CAMERA_OK != cam_evt_buf_done(mCameraId, frame))
1121 {
1122 ALOGE("BUF DONE FAILED");
1123 return BAD_VALUE;
1124 }
1125*/
1126 return NO_ERROR;
1127}
1128
1129
1130status_t QCameraStream_preview::processPreviewFrameWithOutDisplay(
1131 mm_camera_ch_data_buf_t *frame)
1132{
1133 ALOGV("%s",__func__);
1134 int err = 0;
1135 int msgType = 0;
1136 int i;
1137 camera_memory_t *data = NULL;
1138 camera_frame_metadata_t *metadata = NULL;
1139
1140 Mutex::Autolock lock(mStopCallbackLock);
1141 if(!mActive) {
1142 ALOGV("Preview Stopped. Returning callback");
1143 return NO_ERROR;
1144 }
1145 if(mHalCamCtrl==NULL) {
1146 ALOGE("%s: X: HAL control object not set",__func__);
1147 /*Call buf done*/
1148 return BAD_VALUE;
1149 }
1150
1151 if (UNLIKELY(mHalCamCtrl->mDebugFps)) {
1152 mHalCamCtrl->debugShowPreviewFPS();
1153 }
1154 //dumpFrameToFile(frame->def.frame);
1155 mHalCamCtrl->dumpFrameToFile(frame->def.frame, HAL_DUMP_FRM_PREVIEW);
1156
1157 mHalCamCtrl->mPreviewMemoryLock.lock();
1158 mNotifyBuffer[frame->def.idx] = *frame;
1159
1160 /* Save the last displayed frame. We'll be using it to fill the gap between
1161 when preview stops and postview start during snapshot.*/
1162 mLastQueuedFrame = &(mDisplayStreamBuf.frame[frame->def.idx]);
1163 mHalCamCtrl->mPreviewMemoryLock.unlock();
1164
1165 mHalCamCtrl->mCallbackLock.lock();
1166 camera_data_callback pcb = mHalCamCtrl->mDataCb;
1167 mHalCamCtrl->mCallbackLock.unlock();
1168 ALOGV("Message enabled = 0x%x", mHalCamCtrl->mMsgEnabled);
1169
1170 camera_memory_t *previewMem = NULL;
1171 int previewWidth, previewHeight;
1172 mHalCamCtrl->mParameters.getPreviewSize(&previewWidth, &previewHeight);
1173
1174#ifdef USE_ION
1175 struct ion_flush_data cache_inv_data;
1176 int ion_fd;
1177 ion_fd = frame->def.frame->ion_dev_fd;
1178 cache_inv_data.vaddr = (void *)frame->def.frame->buffer;
1179 cache_inv_data.fd = frame->def.frame->fd;
1180 cache_inv_data.handle = frame->def.frame->fd_data.handle;
1181 cache_inv_data.length = frame->def.frame->ion_alloc.len;
1182
1183 if (mHalCamCtrl->cache_ops(ion_fd, &cache_inv_data,
1184 ION_IOC_CLEAN_INV_CACHES) < 0)
1185 ALOGE("%s: Cache clean for Preview buffer %p fd = %d failed", __func__,
1186 cache_inv_data.vaddr, cache_inv_data.fd);
1187#endif
1188
1189 if (pcb != NULL) {
1190 //Sending preview callback if corresponding Msgs are enabled
1191 if(mHalCamCtrl->mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME) {
1192 msgType |= CAMERA_MSG_PREVIEW_FRAME;
1193 int previewBufSize;
1194 /* For CTS : Forcing preview memory buffer lenth to be
1195 'previewWidth * previewHeight * 3/2'.
1196 Needed when gralloc allocated extra memory.*/
1197 //Can add this check for other formats as well.
1198 if( mHalCamCtrl->mPreviewFormat == CAMERA_YUV_420_NV21) {
1199 previewBufSize = previewWidth * previewHeight * 3/2;
1200 if(previewBufSize != mHalCamCtrl->mPreviewMemory.private_buffer_handle[frame->def.idx]->size) {
1201 previewMem = mHalCamCtrl->mGetMemory(mHalCamCtrl->mPreviewMemory.private_buffer_handle[frame->def.idx]->fd,
1202 previewBufSize, 1, mHalCamCtrl->mCallbackCookie);
1203 if (!previewMem || !previewMem->data) {
1204 ALOGE("%s: mGetMemory failed.\n", __func__);
1205 } else {
1206 data = previewMem;
1207 }
1208 } else
1209 data = mHalCamCtrl->mPreviewMemory.camera_memory[frame->def.idx];//mPreviewHeap->mBuffers[frame->def.idx];
1210 } else
1211 data = mHalCamCtrl->mPreviewMemory.camera_memory[frame->def.idx];//mPreviewHeap->mBuffers[frame->def.idx];
1212 } else {
1213 data = NULL;
1214 }
1215
1216 if(mHalCamCtrl->mMsgEnabled & CAMERA_MSG_PREVIEW_METADATA){
1217 msgType |= CAMERA_MSG_PREVIEW_METADATA;
1218 metadata = &mHalCamCtrl->mMetadata;
1219 } else {
1220 metadata = NULL;
1221 }
1222 if(msgType) {
1223 mStopCallbackLock.unlock();
1224 if(mActive)
1225 pcb(msgType, data, 0, metadata, mHalCamCtrl->mCallbackCookie);
1226 if (previewMem)
1227 previewMem->release(previewMem);
1228 mStopCallbackLock.lock();
1229 }
1230
1231 if(MM_CAMERA_OK != cam_evt_buf_done(mCameraId, &mNotifyBuffer[frame->def.idx])) {
1232 ALOGE("BUF DONE FAILED");
1233 }
1234
1235 ALOGV("end of cb");
1236 }
1237
1238 return NO_ERROR;
1239}
1240
1241status_t QCameraStream_preview::processPreviewFrame (
1242 mm_camera_ch_data_buf_t *frame)
1243{
1244 if (mHalCamCtrl->isNoDisplayMode()) {
1245 return processPreviewFrameWithOutDisplay(frame);
1246 } else {
1247 return processPreviewFrameWithDisplay(frame);
1248 }
1249}
1250
1251// ---------------------------------------------------------------------------
1252// QCameraStream_preview
1253// ---------------------------------------------------------------------------
1254
1255QCameraStream_preview::
1256QCameraStream_preview(int cameraId, camera_mode_t mode)
1257 : QCameraStream(cameraId,mode),
1258 mLastQueuedFrame(NULL),
1259 mNumFDRcvd(0),
1260 mFirstFrameRcvd(false)
1261 {
1262 mHalCamCtrl = NULL;
1263 ALOGV("%s: E", __func__);
1264 ALOGV("%s: X", __func__);
1265 }
1266// ---------------------------------------------------------------------------
1267// QCameraStream_preview
1268// ---------------------------------------------------------------------------
1269
1270QCameraStream_preview::~QCameraStream_preview() {
1271 ALOGV("%s: E", __func__);
1272 if(mActive) {
1273 stop();
1274 }
1275 if(mInit) {
1276 release();
1277 }
1278 mInit = false;
1279 mActive = false;
1280 ALOGV("%s: X", __func__);
1281
1282}
1283// ---------------------------------------------------------------------------
1284// QCameraStream_preview
1285// ---------------------------------------------------------------------------
1286
1287status_t QCameraStream_preview::init() {
1288
1289 status_t ret = NO_ERROR;
1290 ALOGV("%s: E", __func__);
1291
1292 ret = QCameraStream::initChannel (mCameraId, MM_CAMERA_CH_PREVIEW_MASK);
1293 if (NO_ERROR!=ret) {
1294 ALOGE("%s E: can't init native cammera preview ch\n",__func__);
1295 return ret;
1296 }
1297
1298 /* register a notify into the mmmm_camera_t object*/
1299 (void) cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_PREVIEW,
1300 preview_notify_cb,
1301 MM_CAMERA_REG_BUF_CB_INFINITE,
1302 0,this);
1303 ALOGV("Debug : %s : cam_evt_register_buf_notify",__func__);
1304 buffer_handle_t *buffer_handle = NULL;
1305 int tmp_stride = 0;
1306 mInit = true;
1307 return ret;
1308}
1309// ---------------------------------------------------------------------------
1310// QCameraStream_preview
1311// ---------------------------------------------------------------------------
1312
1313status_t QCameraStream_preview::start()
1314{
1315 ALOGV("%s: E", __func__);
1316 status_t ret = NO_ERROR;
1317 cam_format_t previewFmt;
1318 Mutex::Autolock lock(mStopCallbackLock);
1319
1320 /* call start() in parent class to start the monitor thread*/
1321 //QCameraStream::start ();
1322 previewFmt = mHalCamCtrl->getPreviewFormat();
1323 setFormat(MM_CAMERA_CH_PREVIEW_MASK, previewFmt);
1324
1325 if (mHalCamCtrl->isNoDisplayMode()) {
1326 if(NO_ERROR!=initPreviewOnlyBuffers()){
1327 return BAD_VALUE;
1328 }
1329 } else {
1330 if(NO_ERROR!=initDisplayBuffers()){
1331 return BAD_VALUE;
1332 }
1333 }
1334 ALOGV("Debug : %s : initDisplayBuffers",__func__);
1335
1336 ret = cam_config_prepare_buf(mCameraId, &mDisplayBuf);
1337 ALOGV("Debug : %s : cam_config_prepare_buf",__func__);
1338 if(ret != MM_CAMERA_OK) {
1339 ALOGV("%s:reg preview buf err=%d\n", __func__, ret);
1340 ret = BAD_VALUE;
1341 goto error;
1342 }else {
1343 ret = NO_ERROR;
1344 }
1345
1346 /* For preview, the OP_MODE we set is dependent upon whether we are
1347 starting camera or camcorder. For snapshot, anyway we disable preview.
1348 However, for ZSL we need to set OP_MODE to OP_MODE_ZSL and not
1349 OP_MODE_VIDEO. We'll set that for now in CamCtrl. So in case of
1350 ZSL we skip setting Mode here */
1351
1352 if (!(myMode & CAMERA_ZSL_MODE)) {
1353 ALOGV("Setting OP MODE to MM_CAMERA_OP_MODE_VIDEO");
1354 mm_camera_op_mode_type_t op_mode=MM_CAMERA_OP_MODE_VIDEO;
1355 ret = cam_config_set_parm (mCameraId, MM_CAMERA_PARM_OP_MODE,
1356 &op_mode);
1357 ALOGV("OP Mode Set");
1358
1359 if(MM_CAMERA_OK != ret) {
1360 ALOGE("%s: X :set mode MM_CAMERA_OP_MODE_VIDEO err=%d\n", __func__, ret);
1361 ret = BAD_VALUE;
1362 goto error;
1363 }
1364 }else {
1365 ALOGV("Setting OP MODE to MM_CAMERA_OP_MODE_ZSL");
1366 mm_camera_op_mode_type_t op_mode=MM_CAMERA_OP_MODE_ZSL;
1367 ret = cam_config_set_parm (mCameraId, MM_CAMERA_PARM_OP_MODE,
1368 &op_mode);
1369 if(MM_CAMERA_OK != ret) {
1370 ALOGE("%s: X :set mode MM_CAMERA_OP_MODE_ZSL err=%d\n", __func__, ret);
1371 ret = BAD_VALUE;
1372 goto error;
1373 }
1374 }
1375
1376 /* call mm_camera action start(...) */
1377 ALOGV("Starting Preview/Video Stream. ");
1378 mFirstFrameRcvd = false;
1379 ret = cam_ops_action(mCameraId, true, MM_CAMERA_OPS_PREVIEW, 0);
1380
1381 if (MM_CAMERA_OK != ret) {
1382 ALOGE ("%s: preview streaming start err=%d\n", __func__, ret);
1383 ret = BAD_VALUE;
1384 goto error;
1385 }
1386
1387 ALOGV("Debug : %s : Preview streaming Started",__func__);
1388 ret = NO_ERROR;
1389
1390 mActive = true;
1391 goto end;
1392
1393error:
1394 putBufferToSurface();
1395end:
1396 ALOGV("%s: X", __func__);
1397 return ret;
1398 }
1399
1400
1401// ---------------------------------------------------------------------------
1402// QCameraStream_preview
1403// ---------------------------------------------------------------------------
1404 void QCameraStream_preview::stop() {
1405 ALOGV("%s: E", __func__);
1406 int ret=MM_CAMERA_OK;
1407
1408 if(!mActive) {
1409 return;
1410 }
1411 Mutex::Autolock lock(mStopCallbackLock);
1412 mActive = false;
1413 /* unregister the notify fn from the mmmm_camera_t object*/
1414
1415 ALOGV("%s: Stop the thread \n", __func__);
1416 /* call stop() in parent class to stop the monitor thread*/
1417 ret = cam_ops_action(mCameraId, false, MM_CAMERA_OPS_PREVIEW, 0);
1418 if(MM_CAMERA_OK != ret) {
1419 ALOGE ("%s: camera preview stop err=%d\n", __func__, ret);
1420 }
1421 ret = cam_config_unprepare_buf(mCameraId, MM_CAMERA_CH_PREVIEW);
1422 if(ret != MM_CAMERA_OK) {
1423 ALOGE("%s:Unreg preview buf err=%d\n", __func__, ret);
1424 //ret = BAD_VALUE;
1425 }
1426
1427 /* In case of a clean stop, we need to clean all buffers*/
1428 ALOGV("Debug : %s : Buffer Unprepared",__func__);
1429 /*free camera_memory handles and return buffer back to surface*/
1430 if (! mHalCamCtrl->isNoDisplayMode() ) {
1431 putBufferToSurface();
1432 } else {
1433 freeBufferNoDisplay( );
1434 }
1435
1436 ALOGV("%s: X", __func__);
1437
1438 }
1439// ---------------------------------------------------------------------------
1440// QCameraStream_preview
1441// ---------------------------------------------------------------------------
1442 void QCameraStream_preview::release() {
1443
1444 ALOGV("%s : BEGIN",__func__);
1445 int ret=MM_CAMERA_OK,i;
1446
1447 if(!mInit)
1448 {
1449 ALOGE("%s : Stream not Initalized",__func__);
1450 return;
1451 }
1452
1453 if(mActive) {
1454 this->stop();
1455 }
1456
1457 ret= QCameraStream::deinitChannel(mCameraId, MM_CAMERA_CH_PREVIEW);
1458 ALOGV("Debug : %s : De init Channel",__func__);
1459 if(ret != MM_CAMERA_OK) {
1460 ALOGE("%s:Deinit preview channel failed=%d\n", __func__, ret);
1461 //ret = BAD_VALUE;
1462 }
1463
1464 (void)cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_PREVIEW,
1465 NULL,
1466 (mm_camera_register_buf_cb_type_t)NULL,
1467 NULL,
1468 NULL);
1469 mInit = false;
1470 ALOGV("%s: END", __func__);
1471
1472 }
1473
1474QCameraStream*
1475QCameraStream_preview::createInstance(int cameraId,
1476 camera_mode_t mode)
1477{
1478 QCameraStream* pme = new QCameraStream_preview(cameraId, mode);
1479 return pme;
1480}
1481// ---------------------------------------------------------------------------
1482// QCameraStream_preview
1483// ---------------------------------------------------------------------------
1484
1485void QCameraStream_preview::deleteInstance(QCameraStream *p)
1486{
1487 if (p){
1488 ALOGV("%s: BEGIN", __func__);
1489 p->release();
1490 delete p;
1491 p = NULL;
1492 ALOGV("%s: END", __func__);
1493 }
1494}
1495
1496
1497/* Temp helper function */
1498void *QCameraStream_preview::getLastQueuedFrame(void)
1499{
1500 return mLastQueuedFrame;
1501}
1502
1503// ---------------------------------------------------------------------------
1504// No code beyone this line
1505// ---------------------------------------------------------------------------
1506}; // namespace android