• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 ** Copyright (c) 2011 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 ALOG_NDEBUG 0
20 #define ALOG_NIDEBUG 0
21 #define LOG_TAG "QCameraHWI_Record"
22 #include <utils/Log.h>
23 #include <utils/threads.h>
24 #include <cutils/properties.h>
25 #include <fcntl.h>
26 #include <sys/mman.h>
27 
28 #include "QCameraStream.h"
29 
30 #define LIKELY(exp)   __builtin_expect(!!(exp), 1)
31 #define UNLIKELY(exp) __builtin_expect(!!(exp), 0)
32 
33 /* QCameraStream_record class implementation goes here*/
34 /* following code implement the video streaming capture & encoding logic of this class*/
35 // ---------------------------------------------------------------------------
36 // QCameraStream_record createInstance()
37 // ---------------------------------------------------------------------------
38 namespace android {
39 
40 
createInstance(int cameraId,camera_mode_t mode)41 QCameraStream* QCameraStream_record::createInstance(int cameraId,
42                                       camera_mode_t mode)
43 {
44   ALOGV("%s: BEGIN", __func__);
45   QCameraStream* pme = new QCameraStream_record(cameraId, mode);
46   ALOGV("%s: END", __func__);
47   return pme;
48 }
49 
50 // ---------------------------------------------------------------------------
51 // QCameraStream_record deleteInstance()
52 // ---------------------------------------------------------------------------
deleteInstance(QCameraStream * ptr)53 void QCameraStream_record::deleteInstance(QCameraStream *ptr)
54 {
55   ALOGV("%s: BEGIN", __func__);
56   if (ptr){
57     ptr->release();
58     delete ptr;
59     ptr = NULL;
60   }
61   ALOGV("%s: END", __func__);
62 }
63 
64 // ---------------------------------------------------------------------------
65 // QCameraStream_record Constructor
66 // ---------------------------------------------------------------------------
QCameraStream_record(int cameraId,camera_mode_t mode)67 QCameraStream_record::QCameraStream_record(int cameraId,
68                                            camera_mode_t mode)
69   :QCameraStream(cameraId,mode),
70   mDebugFps(false)
71 {
72   mHalCamCtrl = NULL;
73   char value[PROPERTY_VALUE_MAX];
74   ALOGV("%s: BEGIN", __func__);
75 
76   property_get("persist.debug.sf.showfps", value, "0");
77   mDebugFps = atoi(value);
78 
79   ALOGV("%s: END", __func__);
80 }
81 
82 // ---------------------------------------------------------------------------
83 // QCameraStream_record Destructor
84 // ---------------------------------------------------------------------------
~QCameraStream_record()85 QCameraStream_record::~QCameraStream_record() {
86   ALOGV("%s: BEGIN", __func__);
87   if(mActive) {
88     stop();
89   }
90   if(mInit) {
91     release();
92   }
93   mInit = false;
94   mActive = false;
95   ALOGV("%s: END", __func__);
96 
97 }
98 
99 // ---------------------------------------------------------------------------
100 // QCameraStream_record Callback from mm_camera
101 // ---------------------------------------------------------------------------
record_notify_cb(mm_camera_ch_data_buf_t * bufs_new,void * user_data)102 static void record_notify_cb(mm_camera_ch_data_buf_t *bufs_new,
103                               void *user_data)
104 {
105   QCameraStream_record *pme = (QCameraStream_record *)user_data;
106   mm_camera_ch_data_buf_t *bufs_used = 0;
107   ALOGV("%s: BEGIN", __func__);
108 
109   /*
110   * Call Function Process Video Data
111   */
112   pme->processRecordFrame(bufs_new);
113   ALOGV("%s: END", __func__);
114 }
115 
116 // ---------------------------------------------------------------------------
117 // QCameraStream_record
118 // ---------------------------------------------------------------------------
init()119 status_t QCameraStream_record::init()
120 {
121   status_t ret = NO_ERROR;
122   ALOGV("%s: BEGIN", __func__);
123 
124   /*
125   *  Acquiring Video Channel
126   */
127   ret = QCameraStream::initChannel (mCameraId, MM_CAMERA_CH_VIDEO_MASK);
128   if (NO_ERROR!=ret) {
129     ALOGE("%s ERROR: Can't init native cammera preview ch\n",__func__);
130     return ret;
131   }
132 
133   /*
134   * Register the Callback with camera
135   */
136   (void) cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_VIDEO,
137                                             record_notify_cb,
138                                             MM_CAMERA_REG_BUF_CB_INFINITE,
139                                             0,
140                                             this);
141 
142   mInit = true;
143   ALOGV("%s: END", __func__);
144   return ret;
145 }
146 // ---------------------------------------------------------------------------
147 // QCameraStream_record
148 // ---------------------------------------------------------------------------
149 
start()150 status_t QCameraStream_record::start()
151 {
152   status_t ret = NO_ERROR;
153   ALOGV("%s: BEGIN", __func__);
154 
155   Mutex::Autolock lock(mStopCallbackLock);
156   if(!mInit) {
157     ALOGE("%s ERROR: Record buffer not registered",__func__);
158     return BAD_VALUE;
159   }
160 
161   setFormat(MM_CAMERA_CH_VIDEO_MASK , (cam_format_t)0);
162   //mRecordFreeQueueLock.lock();
163   //mRecordFreeQueue.clear();
164   //mRecordFreeQueueLock.unlock();
165   /*
166   *  Allocating Encoder Frame Buffers
167   */
168   ret = initEncodeBuffers();
169   if (NO_ERROR!=ret) {
170     ALOGE("%s ERROR: Buffer Allocation Failed\n",__func__);
171     goto error;
172   }
173 
174   ret = cam_config_prepare_buf(mCameraId, &mRecordBuf);
175   if(ret != MM_CAMERA_OK) {
176     ALOGE("%s ERROR: Reg Record buf err=%d\n", __func__, ret);
177     ret = BAD_VALUE;
178     goto error;
179   }else{
180     ret = NO_ERROR;
181   }
182 
183   /*
184   * Start Video Streaming
185   */
186   ret = cam_ops_action(mCameraId, true, MM_CAMERA_OPS_VIDEO, 0);
187   if (MM_CAMERA_OK != ret) {
188     ALOGE ("%s ERROR: Video streaming start err=%d\n", __func__, ret);
189     ret = BAD_VALUE;
190     goto error;
191   }else{
192     ALOGV("%s : Video streaming Started",__func__);
193     ret = NO_ERROR;
194   }
195   mActive = true;
196   ALOGV("%s: END", __func__);
197   return ret;
198 
199 error:
200   releaseEncodeBuffer();
201   ALOGV("%s: END", __func__);
202   return ret;
203 }
204 
releaseEncodeBuffer()205 void QCameraStream_record::releaseEncodeBuffer() {
206   for(int cnt = 0; cnt < mHalCamCtrl->mRecordingMemory.buffer_count; cnt++) {
207     if (NO_ERROR !=
208       mHalCamCtrl->sendUnMappingBuf(MSM_V4L2_EXT_CAPTURE_MODE_VIDEO, cnt,
209       mCameraId, CAM_SOCK_MSG_TYPE_FD_UNMAPPING))
210       ALOGE("%s: Unmapping Video Data Failed", __func__);
211 
212     if (mHalCamCtrl->mStoreMetaDataInFrame) {
213       struct encoder_media_buffer_type * packet =
214           (struct encoder_media_buffer_type  *)
215           mHalCamCtrl->mRecordingMemory.metadata_memory[cnt]->data;
216       native_handle_delete(const_cast<native_handle_t *>(packet->meta_handle));
217       mHalCamCtrl->mRecordingMemory.metadata_memory[cnt]->release(
218         mHalCamCtrl->mRecordingMemory.metadata_memory[cnt]);
219 
220     }
221     mHalCamCtrl->mRecordingMemory.camera_memory[cnt]->release(
222       mHalCamCtrl->mRecordingMemory.camera_memory[cnt]);
223     close(mHalCamCtrl->mRecordingMemory.fd[cnt]);
224     mHalCamCtrl->mRecordingMemory.fd[cnt] = -1;
225 
226 #ifdef USE_ION
227     mHalCamCtrl->deallocate_ion_memory(&mHalCamCtrl->mRecordingMemory, cnt);
228 #endif
229   }
230   memset(&mHalCamCtrl->mRecordingMemory, 0, sizeof(mHalCamCtrl->mRecordingMemory));
231   //mNumRecordFrames = 0;
232   delete[] recordframes;
233   if (mRecordBuf.video.video.buf.mp)
234     delete[] mRecordBuf.video.video.buf.mp;
235 }
236 
237 // ---------------------------------------------------------------------------
238 // QCameraStream_record
239 // ---------------------------------------------------------------------------
stop()240 void QCameraStream_record::stop()
241 {
242   status_t ret = NO_ERROR;
243   ALOGV("%s: BEGIN", __func__);
244 
245   if(!mActive) {
246     ALOGE("%s : Record stream not started",__func__);
247     return;
248   }
249   mActive =  false;
250   Mutex::Autolock lock(mStopCallbackLock);
251 #if 0 //mzhu, when stop recording, all frame will be dirty. no need to queue frame back to kernel any more
252   mRecordFreeQueueLock.lock();
253   while(!mRecordFreeQueue.isEmpty()) {
254     ALOGV("%s : Pre-releasing of Encoder buffers!\n", __FUNCTION__);
255     mm_camera_ch_data_buf_t releasedBuf = mRecordFreeQueue.itemAt(0);
256     mRecordFreeQueue.removeAt(0);
257     mRecordFreeQueueLock.unlock();
258     ALOGV("%s (%d): releasedBuf.idx = %d\n", __FUNCTION__, __LINE__,
259                                               releasedBuf.video.video.idx);
260     if(MM_CAMERA_OK != cam_evt_buf_done(mCameraId,&releasedBuf))
261         ALOGE("%s : Buf Done Failed",__func__);
262   }
263   mRecordFreeQueueLock.unlock();
264 #if 0
265   while (!mRecordFreeQueue.isEmpty()) {
266         ALOGE("%s : Waiting for Encoder to release all buffer!\n", __FUNCTION__);
267   }
268 #endif
269 #endif // mzhu
270   /* unregister the notify fn from the mmmm_camera_t object
271    *  call stop() in parent class to stop the monitor thread */
272 
273   ret = cam_ops_action(mCameraId, false, MM_CAMERA_OPS_VIDEO, 0);
274   if (MM_CAMERA_OK != ret) {
275     ALOGE ("%s ERROR: Video streaming Stop err=%d\n", __func__, ret);
276   }
277 
278   ret = cam_config_unprepare_buf(mCameraId, MM_CAMERA_CH_VIDEO);
279   if(ret != MM_CAMERA_OK){
280     ALOGE("%s ERROR: Ureg video buf \n", __func__);
281   }
282 
283   releaseEncodeBuffer();
284 
285   mActive = false;
286   ALOGV("%s: END", __func__);
287 
288 }
289 // ---------------------------------------------------------------------------
290 // QCameraStream_record
291 // ---------------------------------------------------------------------------
release()292 void QCameraStream_record::release()
293 {
294   status_t ret = NO_ERROR;
295   ALOGV("%s: BEGIN", __func__);
296 
297   if(mActive) {
298     stop();
299   }
300   if(!mInit) {
301     ALOGE("%s : Record stream not initialized",__func__);
302     return;
303   }
304 
305   ret= QCameraStream::deinitChannel(mCameraId, MM_CAMERA_CH_VIDEO);
306   if(ret != MM_CAMERA_OK) {
307     ALOGE("%s:Deinit Video channel failed=%d\n", __func__, ret);
308   }
309   (void)cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_VIDEO,
310                                             NULL,
311                                             (mm_camera_register_buf_cb_type_t)NULL,
312                                             NULL,
313                                             NULL);
314   mInit = false;
315   ALOGV("%s: END", __func__);
316 }
317 
processRecordFrame(void * data)318 status_t QCameraStream_record::processRecordFrame(void *data)
319 {
320     ALOGV("%s : BEGIN",__func__);
321     mm_camera_ch_data_buf_t* frame = (mm_camera_ch_data_buf_t*) data;
322 
323     Mutex::Autolock lock(mStopCallbackLock);
324     if(!mActive) {
325       ALOGE("Recording Stopped. Returning callback");
326       return NO_ERROR;
327     }
328 
329     if (UNLIKELY(mDebugFps)) {
330         debugShowVideoFPS();
331     }
332 
333     mHalCamCtrl->dumpFrameToFile(frame->video.video.frame, HAL_DUMP_FRM_VIDEO);
334     mHalCamCtrl->mCallbackLock.lock();
335     camera_data_timestamp_callback rcb = mHalCamCtrl->mDataCbTimestamp;
336     void *rdata = mHalCamCtrl->mCallbackCookie;
337     mHalCamCtrl->mCallbackLock.unlock();
338 
339 	nsecs_t timeStamp = nsecs_t(frame->video.video.frame->ts.tv_sec)*1000000000LL + \
340                       frame->video.video.frame->ts.tv_nsec;
341 
342   ALOGV("Send Video frame to services/encoder TimeStamp : %lld",timeStamp);
343   mRecordedFrames[frame->video.video.idx] = *frame;
344 
345 #ifdef USE_ION
346   struct ion_flush_data cache_inv_data;
347   int ion_fd;
348   ion_fd = frame->video.video.frame->ion_dev_fd;
349   cache_inv_data.vaddr = (void *)frame->video.video.frame->buffer;
350   cache_inv_data.fd = frame->video.video.frame->fd;
351   cache_inv_data.handle = frame->video.video.frame->fd_data.handle;
352   cache_inv_data.length = frame->video.video.frame->ion_alloc.len;
353 
354   if (mHalCamCtrl->cache_ops(ion_fd, &cache_inv_data, ION_IOC_CLEAN_CACHES) < 0)
355     ALOGE("%s: Cache clean for Video buffer %p fd = %d failed", __func__,
356       cache_inv_data.vaddr, cache_inv_data.fd);
357 #endif
358 
359   if (mHalCamCtrl->mStoreMetaDataInFrame) {
360     mStopCallbackLock.unlock();
361     if(mActive && (rcb != NULL) && (mHalCamCtrl->mMsgEnabled & CAMERA_MSG_VIDEO_FRAME)) {
362       rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME,
363               mHalCamCtrl->mRecordingMemory.metadata_memory[frame->video.video.idx],
364               0, mHalCamCtrl->mCallbackCookie);
365     }
366   } else {
367     mStopCallbackLock.unlock();
368     if(mActive && (rcb != NULL) && (mHalCamCtrl->mMsgEnabled & CAMERA_MSG_VIDEO_FRAME)) {
369       rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME,
370               mHalCamCtrl->mRecordingMemory.camera_memory[frame->video.video.idx],
371               0, mHalCamCtrl->mCallbackCookie);
372     }
373   }
374 
375   ALOGV("%s : END",__func__);
376   return NO_ERROR;
377 }
378 
379 //Record Related Functions
initEncodeBuffers()380 status_t QCameraStream_record::initEncodeBuffers()
381 {
382   ALOGV("%s : BEGIN",__func__);
383   status_t ret = NO_ERROR;
384   const char *pmem_region;
385   uint32_t frame_len;
386   uint8_t num_planes;
387   uint32_t planes[VIDEO_MAX_PLANES];
388   //cam_ctrl_dimension_t dim;
389   int width = 0;  /* width of channel  */
390   int height = 0; /* height of channel */
391   int buf_cnt;
392   pmem_region = "/dev/pmem_adsp";
393 
394 
395   memset(&mHalCamCtrl->mRecordingMemory, 0, sizeof(mHalCamCtrl->mRecordingMemory));
396   memset(&dim, 0, sizeof(cam_ctrl_dimension_t));
397   ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION, &dim);
398   if (MM_CAMERA_OK != ret) {
399     ALOGE("%s: ERROR - can't get camera dimension!", __func__);
400     return BAD_VALUE;
401   }
402   else {
403     width =  dim.video_width;
404     height = dim.video_height;
405   }
406   num_planes = 2;
407   planes[0] = dim.video_frame_offset.mp[0].len;
408   planes[1] = dim.video_frame_offset.mp[1].len;
409   frame_len = dim.video_frame_offset.frame_len;
410 
411   buf_cnt = VIDEO_BUFFER_COUNT;
412   if(mHalCamCtrl->isLowPowerCamcorder()) {
413     ALOGV("%s: lower power camcorder selected", __func__);
414     buf_cnt = VIDEO_BUFFER_COUNT_LOW_POWER_CAMCORDER;
415   }
416     recordframes = new msm_frame[buf_cnt];
417     memset(recordframes,0,sizeof(struct msm_frame) * buf_cnt);
418 
419 		mRecordBuf.video.video.buf.mp = new mm_camera_mp_buf_t[buf_cnt *
420                                   sizeof(mm_camera_mp_buf_t)];
421 		if (!mRecordBuf.video.video.buf.mp) {
422 			ALOGE("%s Error allocating memory for mplanar struct ", __func__);
423 			return BAD_VALUE;
424 		}
425 		memset(mRecordBuf.video.video.buf.mp, 0,
426 					 buf_cnt * sizeof(mm_camera_mp_buf_t));
427 
428     memset(&mHalCamCtrl->mRecordingMemory, 0, sizeof(mHalCamCtrl->mRecordingMemory));
429     for (int i=0; i<MM_CAMERA_MAX_NUM_FRAMES;i++) {
430         mHalCamCtrl->mRecordingMemory.main_ion_fd[i] = -1;
431         mHalCamCtrl->mRecordingMemory.fd[i] = -1;
432     }
433 
434     mHalCamCtrl->mRecordingMemory.buffer_count = buf_cnt;
435 
436 		mHalCamCtrl->mRecordingMemory.size = frame_len;
437 		mHalCamCtrl->mRecordingMemory.cbcr_offset = planes[0];
438 
439     for (int cnt = 0; cnt < mHalCamCtrl->mRecordingMemory.buffer_count; cnt++) {
440 #ifdef USE_ION
441       if(mHalCamCtrl->allocate_ion_memory(&mHalCamCtrl->mRecordingMemory, cnt,
442         ((0x1 << CAMERA_ION_HEAP_ID) | (0x1 << CAMERA_ION_FALLBACK_HEAP_ID))) < 0) {
443         ALOGE("%s ION alloc failed\n", __func__);
444         return UNKNOWN_ERROR;
445       }
446 #else
447 		  mHalCamCtrl->mRecordingMemory.fd[cnt] = open("/dev/pmem_adsp", O_RDWR|O_SYNC);
448 		  if(mHalCamCtrl->mRecordingMemory.fd[cnt] <= 0) {
449 			  ALOGE("%s: no pmem for frame %d", __func__, cnt);
450 			  return UNKNOWN_ERROR;
451 		  }
452 #endif
453 		  mHalCamCtrl->mRecordingMemory.camera_memory[cnt] =
454 		    mHalCamCtrl->mGetMemory(mHalCamCtrl->mRecordingMemory.fd[cnt],
455 		    mHalCamCtrl->mRecordingMemory.size, 1, (void *)this);
456 
457       if (mHalCamCtrl->mStoreMetaDataInFrame) {
458         mHalCamCtrl->mRecordingMemory.metadata_memory[cnt] =
459           mHalCamCtrl->mGetMemory(-1,
460           sizeof(struct encoder_media_buffer_type), 1, (void *)this);
461         struct encoder_media_buffer_type * packet =
462           (struct encoder_media_buffer_type  *)
463           mHalCamCtrl->mRecordingMemory.metadata_memory[cnt]->data;
464         packet->meta_handle = native_handle_create(1, 2); //1 fd, 1 offset and 1 size
465         packet->buffer_type = kMetadataBufferTypeCameraSource;
466         native_handle_t * nh = const_cast<native_handle_t *>(packet->meta_handle);
467         nh->data[0] = mHalCamCtrl->mRecordingMemory.fd[cnt];
468         nh->data[1] = 0;
469         nh->data[2] = mHalCamCtrl->mRecordingMemory.size;
470       }
471     	recordframes[cnt].fd = mHalCamCtrl->mRecordingMemory.fd[cnt];
472     	recordframes[cnt].buffer = (uint32_t)mHalCamCtrl->mRecordingMemory.camera_memory[cnt]->data;
473 	    recordframes[cnt].y_off = 0;
474 	    recordframes[cnt].cbcr_off = mHalCamCtrl->mRecordingMemory.cbcr_offset;
475 	    recordframes[cnt].path = OUTPUT_TYPE_V;
476       recordframes[cnt].fd_data = mHalCamCtrl->mRecordingMemory.ion_info_fd[cnt];
477       recordframes[cnt].ion_alloc = mHalCamCtrl->mRecordingMemory.alloc[cnt];
478       recordframes[cnt].ion_dev_fd = mHalCamCtrl->mRecordingMemory.main_ion_fd[cnt];
479 
480       if (NO_ERROR !=
481         mHalCamCtrl->sendMappingBuf(MSM_V4L2_EXT_CAPTURE_MODE_VIDEO, cnt,
482         recordframes[cnt].fd, mHalCamCtrl->mRecordingMemory.size, mCameraId,
483         CAM_SOCK_MSG_TYPE_FD_MAPPING))
484         ALOGE("%s: sending mapping data Msg Failed", __func__);
485 
486       ALOGV("initRecord :  record heap , video buffers  buffer=%lu fd=%d y_off=%d cbcr_off=%d\n",
487 		    (unsigned long)recordframes[cnt].buffer, recordframes[cnt].fd, recordframes[cnt].y_off,
488 		    recordframes[cnt].cbcr_off);
489 	    //mNumRecordFrames++;
490 
491 			mRecordBuf.video.video.buf.mp[cnt].frame = recordframes[cnt];
492       mRecordBuf.video.video.buf.mp[cnt].frame_offset = 0;
493       mRecordBuf.video.video.buf.mp[cnt].num_planes = num_planes;
494       /* Plane 0 needs to be set seperately. Set other planes
495        * in a loop. */
496       mRecordBuf.video.video.buf.mp[cnt].planes[0].reserved[0] =
497         mRecordBuf.video.video.buf.mp[cnt].frame_offset;
498       mRecordBuf.video.video.buf.mp[cnt].planes[0].length = planes[0];
499       mRecordBuf.video.video.buf.mp[cnt].planes[0].m.userptr =
500         recordframes[cnt].fd;
501       for (int j = 1; j < num_planes; j++) {
502         mRecordBuf.video.video.buf.mp[cnt].planes[j].length = planes[j];
503         mRecordBuf.video.video.buf.mp[cnt].planes[j].m.userptr =
504           recordframes[cnt].fd;
505         mRecordBuf.video.video.buf.mp[cnt].planes[j].reserved[0] =
506           mRecordBuf.video.video.buf.mp[cnt].planes[j-1].reserved[0] +
507           mRecordBuf.video.video.buf.mp[cnt].planes[j-1].length;
508       }
509     }
510 
511     //memset(&mRecordBuf, 0, sizeof(mRecordBuf));
512     mRecordBuf.ch_type = MM_CAMERA_CH_VIDEO;
513     mRecordBuf.video.video.num = mHalCamCtrl->mRecordingMemory.buffer_count;//kRecordBufferCount;
514     //mRecordBuf.video.video.frame_offset = &record_offset[0];
515     //mRecordBuf.video.video.frame = &recordframes[0];
516     ALOGV("%s : END",__func__);
517     return NO_ERROR;
518 }
519 
releaseRecordingFrame(const void * opaque)520 void QCameraStream_record::releaseRecordingFrame(const void *opaque)
521 {
522     ALOGV("%s : BEGIN, opaque = 0x%p",__func__, opaque);
523     if(!mActive)
524     {
525         ALOGE("%s : Recording already stopped!!! Leak???",__func__);
526         return;
527     }
528     for(int cnt = 0; cnt < mHalCamCtrl->mRecordingMemory.buffer_count; cnt++) {
529       if (mHalCamCtrl->mStoreMetaDataInFrame) {
530         if(mHalCamCtrl->mRecordingMemory.metadata_memory[cnt] &&
531                 mHalCamCtrl->mRecordingMemory.metadata_memory[cnt]->data == opaque) {
532             /* found the match */
533             if(MM_CAMERA_OK != cam_evt_buf_done(mCameraId, &mRecordedFrames[cnt]))
534                 ALOGE("%s : Buf Done Failed",__func__);
535             ALOGV("%s : END",__func__);
536             return;
537         }
538       } else {
539         if(mHalCamCtrl->mRecordingMemory.camera_memory[cnt] &&
540                 mHalCamCtrl->mRecordingMemory.camera_memory[cnt]->data == opaque) {
541             /* found the match */
542             if(MM_CAMERA_OK != cam_evt_buf_done(mCameraId, &mRecordedFrames[cnt]))
543                 ALOGE("%s : Buf Done Failed",__func__);
544             ALOGV("%s : END",__func__);
545             return;
546         }
547       }
548     }
549 	ALOGE("%s: cannot find the matched frame with opaue = 0x%p", __func__, opaque);
550 }
551 
debugShowVideoFPS() const552 void QCameraStream_record::debugShowVideoFPS() const
553 {
554   static int mFrameCount;
555   static int mLastFrameCount = 0;
556   static nsecs_t mLastFpsTime = 0;
557   static float mFps = 0;
558   mFrameCount++;
559   nsecs_t now = systemTime();
560   nsecs_t diff = now - mLastFpsTime;
561   if (diff > ms2ns(250)) {
562     mFps =  ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
563     ALOGV("Video Frames Per Second: %.4f", mFps);
564     mLastFpsTime = now;
565     mLastFrameCount = mFrameCount;
566   }
567 }
568 
569 #if 0
570 sp<IMemoryHeap> QCameraStream_record::getHeap() const
571 {
572   return mRecordHeap != NULL ? mRecordHeap->mHeap : NULL;
573 }
574 
575 #endif
takeLiveSnapshot()576 status_t  QCameraStream_record::takeLiveSnapshot(){
577 	return true;
578 }
579 
580 }//namespace android
581 
582