1 /* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
2  *
3  * Redistribution and use in source and binary forms, with or without
4  * modification, are permitted provided that the following conditions are
5  * met:
6  *     * Redistributions of source code must retain the above copyright
7  *       notice, this list of conditions and the following disclaimer.
8  *     * Redistributions in binary form must reproduce the above
9  *       copyright notice, this list of conditions and the following
10  *       disclaimer in the documentation and/or other materials provided
11  *       with the distribution.
12  *     * Neither the name of The Linux Foundation nor the names of its
13  *       contributors may be used to endorse or promote products derived
14  *       from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  */
29 
30 #include "mm_qcamera_dbg.h"
31 #include "mm_qcamera_app.h"
32 
33 /* This callback is received once the complete JPEG encoding is done */
jpeg_encode_cb(jpeg_job_status_t status,uint32_t client_hdl,uint32_t jobId,mm_jpeg_output_t * p_buf,void * userData)34 static void jpeg_encode_cb(jpeg_job_status_t status,
35                            uint32_t client_hdl,
36                            uint32_t jobId,
37                            mm_jpeg_output_t *p_buf,
38                            void *userData)
39 {
40     int i = 0;
41     mm_camera_test_obj_t *pme = NULL;
42     CDBG("%s: BEGIN\n", __func__);
43 
44     pme = (mm_camera_test_obj_t *)userData;
45     if (pme->jpeg_hdl != client_hdl ||
46         jobId != pme->current_job_id ||
47         !pme->current_job_frames) {
48         CDBG_ERROR("%s: NULL current job frames or not matching job ID (%d, %d)",
49                    __func__, jobId, pme->current_job_id);
50         return;
51     }
52 
53     /* dump jpeg img */
54     CDBG_ERROR("%s: job %d, status=%d", __func__, jobId, status);
55     if (status == JPEG_JOB_STATUS_DONE && p_buf != NULL) {
56         mm_app_dump_jpeg_frame(p_buf->buf_vaddr, p_buf->buf_filled_len, "jpeg", "jpg", jobId);
57     }
58 
59     /* buf done current encoding frames */
60     pme->current_job_id = 0;
61     for (i = 0; i < pme->current_job_frames->num_bufs; i++) {
62         if (MM_CAMERA_OK != pme->cam->ops->qbuf(pme->current_job_frames->camera_handle,
63                                                 pme->current_job_frames->ch_id,
64                                                 pme->current_job_frames->bufs[i])) {
65             CDBG_ERROR("%s: Failed in Qbuf\n", __func__);
66         }
67         mm_app_cache_ops((mm_camera_app_meminfo_t *) pme->current_job_frames->bufs[i]->mem_info,
68                          ION_IOC_INV_CACHES);
69     }
70 
71     free(pme->jpeg_buf.buf.buffer);
72     free(pme->current_job_frames);
73     pme->current_job_frames = NULL;
74 
75     /* signal snapshot is done */
76     mm_camera_app_done();
77 }
78 
encodeData(mm_camera_test_obj_t * test_obj,mm_camera_super_buf_t * recvd_frame,mm_camera_stream_t * m_stream)79 int encodeData(mm_camera_test_obj_t *test_obj, mm_camera_super_buf_t* recvd_frame,
80                mm_camera_stream_t *m_stream)
81 {
82     cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
83 
84     int rc = -MM_CAMERA_E_GENERAL;
85     mm_jpeg_job_t job;
86 
87     /* remember current frames being encoded */
88     test_obj->current_job_frames =
89         (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t));
90     if (!test_obj->current_job_frames) {
91         CDBG_ERROR("%s: No memory for current_job_frames", __func__);
92         return rc;
93     }
94     *(test_obj->current_job_frames) = *recvd_frame;
95 
96     memset(&job, 0, sizeof(job));
97     job.job_type = JPEG_JOB_TYPE_ENCODE;
98     job.encode_job.session_id = test_obj->current_jpeg_sess_id;
99 
100     // TODO: Rotation should be set according to
101     //       sensor&device orientation
102     job.encode_job.rotation = 0;
103     if (cam_cap->position == CAM_POSITION_BACK) {
104         job.encode_job.rotation = 270;
105     }
106 
107     /* fill in main src img encode param */
108     job.encode_job.main_dim.src_dim = m_stream->s_config.stream_info->dim;
109     job.encode_job.main_dim.dst_dim = m_stream->s_config.stream_info->dim;
110     job.encode_job.src_index = 0;
111 
112     job.encode_job.thumb_dim.src_dim = m_stream->s_config.stream_info->dim;
113     job.encode_job.thumb_dim.dst_dim.width = DEFAULT_PREVIEW_WIDTH;
114     job.encode_job.thumb_dim.dst_dim.height = DEFAULT_PREVIEW_HEIGHT;
115 
116     /* fill in sink img param */
117     job.encode_job.dst_index = 0;
118 
119     if (test_obj->metadata != NULL) {
120         job.encode_job.p_metadata = test_obj->metadata;
121     } else {
122         CDBG_ERROR("%s: Metadata null, not set for jpeg encoding", __func__);
123     }
124 
125     rc = test_obj->jpeg_ops.start_job(&job, &test_obj->current_job_id);
126     if ( 0 != rc ) {
127         free(test_obj->current_job_frames);
128         test_obj->current_job_frames = NULL;
129     }
130 
131     return rc;
132 }
133 
createEncodingSession(mm_camera_test_obj_t * test_obj,mm_camera_stream_t * m_stream,mm_camera_buf_def_t * m_frame)134 int createEncodingSession(mm_camera_test_obj_t *test_obj,
135                           mm_camera_stream_t *m_stream,
136                           mm_camera_buf_def_t *m_frame)
137 {
138     mm_jpeg_encode_params_t encode_param;
139 
140     memset(&encode_param, 0, sizeof(mm_jpeg_encode_params_t));
141     encode_param.jpeg_cb = jpeg_encode_cb;
142     encode_param.userdata = (void*)test_obj;
143     encode_param.encode_thumbnail = 0;
144     encode_param.quality = 85;
145     encode_param.color_format = MM_JPEG_COLOR_FORMAT_YCRCBLP_H2V2;
146     encode_param.thumb_color_format = MM_JPEG_COLOR_FORMAT_YCRCBLP_H2V2;
147 
148     /* fill in main src img encode param */
149     encode_param.num_src_bufs = 1;
150     encode_param.src_main_buf[0].index = 0;
151     encode_param.src_main_buf[0].buf_size = m_frame->frame_len;
152     encode_param.src_main_buf[0].buf_vaddr = (uint8_t *)m_frame->buffer;
153     encode_param.src_main_buf[0].fd = m_frame->fd;
154     encode_param.src_main_buf[0].format = MM_JPEG_FMT_YUV;
155     encode_param.src_main_buf[0].offset = m_stream->offset;
156 
157     /* fill in sink img param */
158     encode_param.num_dst_bufs = 1;
159     encode_param.dest_buf[0].index = 0;
160     encode_param.dest_buf[0].buf_size = test_obj->jpeg_buf.buf.frame_len;
161     encode_param.dest_buf[0].buf_vaddr = (uint8_t *)test_obj->jpeg_buf.buf.buffer;
162     encode_param.dest_buf[0].fd = test_obj->jpeg_buf.buf.fd;
163     encode_param.dest_buf[0].format = MM_JPEG_FMT_YUV;
164 
165     /* main dimension */
166     encode_param.main_dim.src_dim = m_stream->s_config.stream_info->dim;
167     encode_param.main_dim.dst_dim = m_stream->s_config.stream_info->dim;
168 
169     return test_obj->jpeg_ops.create_session(test_obj->jpeg_hdl,
170                                              &encode_param,
171                                              &test_obj->current_jpeg_sess_id);
172 }
173 
174 /** mm_app_snapshot_metadata_notify_cb
175  *  @bufs: Pointer to super buffer
176  *  @user_data: Pointer to user data
177  *
178  *
179  **/
mm_app_snapshot_metadata_notify_cb(mm_camera_super_buf_t * bufs,void * user_data)180 static void mm_app_snapshot_metadata_notify_cb(mm_camera_super_buf_t *bufs,
181   void *user_data)
182 {
183   int i = 0;
184   mm_camera_channel_t *channel = NULL;
185   mm_camera_stream_t *p_stream = NULL;
186   mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
187   mm_camera_buf_def_t *frame = bufs->bufs[0];
188   metadata_buffer_t *pMetadata;
189   cam_auto_focus_data_t *focus_data;
190 
191   if (NULL == bufs || NULL == user_data) {
192     CDBG_ERROR("%s: bufs or user_data are not valid ", __func__);
193     return;
194   }
195 
196   /* find channel */
197   for (i = 0; i < MM_CHANNEL_TYPE_MAX; i++) {
198     if (pme->channels[i].ch_id == bufs->ch_id) {
199       channel = &pme->channels[i];
200       break;
201     }
202   }
203   /* find meta stream */
204   for (i = 0; i < channel->num_streams; i++) {
205     if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_METADATA) {
206       p_stream = &channel->streams[i];
207       break;
208     }
209   }
210   /* find meta frame */
211   for (i = 0; i < bufs->num_bufs; i++) {
212     if (bufs->bufs[i]->stream_id == p_stream->s_id) {
213       frame = bufs->bufs[i];
214       break;
215     }
216   }
217 
218   if (NULL == p_stream) {
219     CDBG_ERROR("%s: cannot find metadata stream", __func__);
220     return;
221   }
222   if (!pme->metadata) {
223     /* The app will free the metadata, we don't need to bother here */
224     pme->metadata = malloc(sizeof(metadata_buffer_t));
225   }
226   memcpy(pme->metadata , frame->buffer, sizeof(metadata_buffer_t));
227 
228   pMetadata = (metadata_buffer_t *)frame->buffer;
229 
230   if (IS_META_AVAILABLE(CAM_INTF_META_AUTOFOCUS_DATA, pMetadata)) {
231     focus_data = (cam_auto_focus_data_t *)
232       POINTER_OF_META(CAM_INTF_META_AUTOFOCUS_DATA, pMetadata);
233     if (focus_data->focus_state == CAM_AF_FOCUSED) {
234       CDBG_ERROR("%s: AutoFocus Done Call Back Received\n",__func__);
235       mm_camera_app_done();
236     } else if (focus_data->focus_state == CAM_AF_NOT_FOCUSED) {
237       CDBG_ERROR("%s: AutoFocus failed\n",__func__);
238       mm_camera_app_done();
239     }
240   }
241 
242   if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
243                                           bufs->ch_id,
244                                           frame)) {
245     CDBG_ERROR("%s: Failed in Preview Qbuf\n", __func__);
246   }
247   mm_app_cache_ops((mm_camera_app_meminfo_t *)frame->mem_info,
248                    ION_IOC_INV_CACHES);
249 }
250 
mm_app_snapshot_notify_cb_raw(mm_camera_super_buf_t * bufs,void * user_data)251 static void mm_app_snapshot_notify_cb_raw(mm_camera_super_buf_t *bufs,
252                                           void *user_data)
253 {
254 
255     int rc;
256     int i = 0;
257     mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
258     mm_camera_channel_t *channel = NULL;
259     mm_camera_stream_t *m_stream = NULL;
260     mm_camera_buf_def_t *m_frame = NULL;
261 
262     CDBG("%s: BEGIN\n", __func__);
263 
264     /* find channel */
265     for (i = 0; i < MM_CHANNEL_TYPE_MAX; i++) {
266         if (pme->channels[i].ch_id == bufs->ch_id) {
267             channel = &pme->channels[i];
268             break;
269         }
270     }
271     if (NULL == channel) {
272         CDBG_ERROR("%s: Wrong channel id (%d)", __func__, bufs->ch_id);
273         rc = -1;
274         goto EXIT;
275     }
276 
277     /* find snapshot stream */
278     for (i = 0; i < channel->num_streams; i++) {
279         if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_RAW) {
280             m_stream = &channel->streams[i];
281             break;
282         }
283     }
284     if (NULL == m_stream) {
285         CDBG_ERROR("%s: cannot find snapshot stream", __func__);
286         rc = -1;
287         goto EXIT;
288     }
289 
290     /* find snapshot frame */
291     for (i = 0; i < bufs->num_bufs; i++) {
292         if (bufs->bufs[i]->stream_id == m_stream->s_id) {
293             m_frame = bufs->bufs[i];
294             break;
295         }
296     }
297     if (NULL == m_frame) {
298         CDBG_ERROR("%s: main frame is NULL", __func__);
299         rc = -1;
300         goto EXIT;
301     }
302 
303     mm_app_dump_frame(m_frame, "main", "raw", m_frame->frame_idx);
304 
305 EXIT:
306     for (i=0; i<bufs->num_bufs; i++) {
307         if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
308                                                 bufs->ch_id,
309                                                 bufs->bufs[i])) {
310             CDBG_ERROR("%s: Failed in Qbuf\n", __func__);
311         }
312     }
313 
314     mm_camera_app_done();
315 
316     CDBG("%s: END\n", __func__);
317 }
318 
mm_app_snapshot_notify_cb(mm_camera_super_buf_t * bufs,void * user_data)319 static void mm_app_snapshot_notify_cb(mm_camera_super_buf_t *bufs,
320                                       void *user_data)
321 {
322 
323     int rc = 0;
324     int i = 0;
325     mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
326     mm_camera_channel_t *channel = NULL;
327     mm_camera_stream_t *p_stream = NULL;
328     mm_camera_stream_t *m_stream = NULL;
329     mm_camera_buf_def_t *p_frame = NULL;
330     mm_camera_buf_def_t *m_frame = NULL;
331 
332     CDBG("%s: BEGIN\n", __func__);
333 
334     /* find channel */
335     for (i = 0; i < MM_CHANNEL_TYPE_MAX; i++) {
336         if (pme->channels[i].ch_id == bufs->ch_id) {
337             channel = &pme->channels[i];
338             break;
339         }
340     }
341     if (NULL == channel) {
342         CDBG_ERROR("%s: Wrong channel id (%d)", __func__, bufs->ch_id);
343         rc = -1;
344         goto error;
345     }
346 
347     /* find snapshot stream */
348     for (i = 0; i < channel->num_streams; i++) {
349         if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_SNAPSHOT) {
350             m_stream = &channel->streams[i];
351             break;
352         }
353     }
354     if (NULL == m_stream) {
355         CDBG_ERROR("%s: cannot find snapshot stream", __func__);
356         rc = -1;
357         goto error;
358     }
359 
360     /* find snapshot frame */
361     for (i = 0; i < bufs->num_bufs; i++) {
362         if (bufs->bufs[i]->stream_id == m_stream->s_id) {
363             m_frame = bufs->bufs[i];
364             break;
365         }
366     }
367     if (NULL == m_frame) {
368         CDBG_ERROR("%s: main frame is NULL", __func__);
369         rc = -1;
370         goto error;
371     }
372 
373     mm_app_dump_frame(m_frame, "main", "yuv", m_frame->frame_idx);
374 
375     /* find postview stream */
376     for (i = 0; i < channel->num_streams; i++) {
377         if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_POSTVIEW) {
378             p_stream = &channel->streams[i];
379             break;
380         }
381     }
382     if (NULL != p_stream) {
383         /* find preview frame */
384         for (i = 0; i < bufs->num_bufs; i++) {
385             if (bufs->bufs[i]->stream_id == p_stream->s_id) {
386                 p_frame = bufs->bufs[i];
387                 break;
388             }
389         }
390         if (NULL != p_frame) {
391             mm_app_dump_frame(p_frame, "postview", "yuv", p_frame->frame_idx);
392         }
393     }
394 
395     mm_app_cache_ops((mm_camera_app_meminfo_t *)m_frame->mem_info,
396                      ION_IOC_CLEAN_INV_CACHES);
397 
398     pme->jpeg_buf.buf.buffer = (uint8_t *)malloc(m_frame->frame_len);
399     if ( NULL == pme->jpeg_buf.buf.buffer ) {
400         CDBG_ERROR("%s: error allocating jpeg output buffer", __func__);
401         goto error;
402     }
403 
404     pme->jpeg_buf.buf.frame_len = m_frame->frame_len;
405     /* create a new jpeg encoding session */
406     rc = createEncodingSession(pme, m_stream, m_frame);
407     if (0 != rc) {
408         CDBG_ERROR("%s: error creating jpeg session", __func__);
409         free(pme->jpeg_buf.buf.buffer);
410         goto error;
411     }
412 
413     /* start jpeg encoding job */
414     rc = encodeData(pme, bufs, m_stream);
415     if (0 != rc) {
416         CDBG_ERROR("%s: error creating jpeg session", __func__);
417         free(pme->jpeg_buf.buf.buffer);
418         goto error;
419     }
420 
421 error:
422     /* buf done rcvd frames in error case */
423     if ( 0 != rc ) {
424         for (i=0; i<bufs->num_bufs; i++) {
425             if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
426                                                     bufs->ch_id,
427                                                     bufs->bufs[i])) {
428                 CDBG_ERROR("%s: Failed in Qbuf\n", __func__);
429             }
430             mm_app_cache_ops((mm_camera_app_meminfo_t *)bufs->bufs[i]->mem_info,
431                              ION_IOC_INV_CACHES);
432         }
433     }
434 
435     CDBG("%s: END\n", __func__);
436 }
437 
mm_app_add_snapshot_channel(mm_camera_test_obj_t * test_obj)438 mm_camera_channel_t * mm_app_add_snapshot_channel(mm_camera_test_obj_t *test_obj)
439 {
440     mm_camera_channel_t *channel = NULL;
441     mm_camera_stream_t *stream = NULL;
442 
443     channel = mm_app_add_channel(test_obj,
444                                  MM_CHANNEL_TYPE_SNAPSHOT,
445                                  NULL,
446                                  NULL,
447                                  NULL);
448     if (NULL == channel) {
449         CDBG_ERROR("%s: add channel failed", __func__);
450         return NULL;
451     }
452 
453     stream = mm_app_add_snapshot_stream(test_obj,
454                                         channel,
455                                         mm_app_snapshot_notify_cb,
456                                         (void *)test_obj,
457                                         1,
458                                         1);
459     if (NULL == stream) {
460         CDBG_ERROR("%s: add snapshot stream failed\n", __func__);
461         mm_app_del_channel(test_obj, channel);
462         return NULL;
463     }
464 
465     return channel;
466 }
467 
mm_app_add_postview_stream(mm_camera_test_obj_t * test_obj,mm_camera_channel_t * channel,mm_camera_buf_notify_t stream_cb,void * userdata,uint8_t num_bufs,uint8_t num_burst)468 mm_camera_stream_t * mm_app_add_postview_stream(mm_camera_test_obj_t *test_obj,
469                                                 mm_camera_channel_t *channel,
470                                                 mm_camera_buf_notify_t stream_cb,
471                                                 void *userdata,
472                                                 uint8_t num_bufs,
473                                                 uint8_t num_burst)
474 {
475     int rc = MM_CAMERA_OK;
476     mm_camera_stream_t *stream = NULL;
477     cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
478 
479     stream = mm_app_add_stream(test_obj, channel);
480     if (NULL == stream) {
481         CDBG_ERROR("%s: add stream failed\n", __func__);
482         return NULL;
483     }
484 
485     stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
486     stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
487     stream->s_config.mem_vtbl.clean_invalidate_buf =
488       mm_app_stream_clean_invalidate_buf;
489     stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
490     stream->s_config.mem_vtbl.user_data = (void *)stream;
491     stream->s_config.stream_cb = stream_cb;
492     stream->s_config.userdata = userdata;
493     stream->num_of_bufs = num_bufs;
494 
495     stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
496     memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
497     stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_POSTVIEW;
498     if (num_burst == 0) {
499         stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
500     } else {
501         stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_BURST;
502         stream->s_config.stream_info->num_of_burst = num_burst;
503     }
504     stream->s_config.stream_info->fmt = DEFAULT_PREVIEW_FORMAT;
505     stream->s_config.stream_info->dim.width = DEFAULT_PREVIEW_WIDTH;
506     stream->s_config.stream_info->dim.height = DEFAULT_PREVIEW_HEIGHT;
507     stream->s_config.padding_info = cam_cap->padding_info;
508 
509     rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
510     if (MM_CAMERA_OK != rc) {
511         CDBG_ERROR("%s:config preview stream err=%d\n", __func__, rc);
512         return NULL;
513     }
514 
515     return stream;
516 }
517 
mm_app_start_capture_raw(mm_camera_test_obj_t * test_obj,uint8_t num_snapshots)518 int mm_app_start_capture_raw(mm_camera_test_obj_t *test_obj, uint8_t num_snapshots)
519 {
520     int32_t rc = MM_CAMERA_OK;
521     mm_camera_channel_t *channel = NULL;
522     mm_camera_stream_t *s_main = NULL;
523     mm_camera_channel_attr_t attr;
524 
525     memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
526     attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
527     attr.max_unmatched_frames = 3;
528     channel = mm_app_add_channel(test_obj,
529                                  MM_CHANNEL_TYPE_CAPTURE,
530                                  &attr,
531                                  mm_app_snapshot_notify_cb_raw,
532                                  test_obj);
533     if (NULL == channel) {
534         CDBG_ERROR("%s: add channel failed", __func__);
535         return -MM_CAMERA_E_GENERAL;
536     }
537 
538     test_obj->buffer_format = DEFAULT_RAW_FORMAT;
539     s_main = mm_app_add_raw_stream(test_obj,
540                                    channel,
541                                    mm_app_snapshot_notify_cb_raw,
542                                    test_obj,
543                                    num_snapshots,
544                                    num_snapshots);
545     if (NULL == s_main) {
546         CDBG_ERROR("%s: add main snapshot stream failed\n", __func__);
547         mm_app_del_channel(test_obj, channel);
548         return rc;
549     }
550 
551     rc = mm_app_start_channel(test_obj, channel);
552     if (MM_CAMERA_OK != rc) {
553         CDBG_ERROR("%s:start zsl failed rc=%d\n", __func__, rc);
554         mm_app_del_stream(test_obj, channel, s_main);
555         mm_app_del_channel(test_obj, channel);
556         return rc;
557     }
558 
559     return rc;
560 }
561 
mm_app_stop_capture_raw(mm_camera_test_obj_t * test_obj)562 int mm_app_stop_capture_raw(mm_camera_test_obj_t *test_obj)
563 {
564     int rc = MM_CAMERA_OK;
565     mm_camera_channel_t *ch = NULL;
566     int i;
567 
568     ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_CAPTURE);
569 
570     rc = mm_app_stop_channel(test_obj, ch);
571     if (MM_CAMERA_OK != rc) {
572         CDBG_ERROR("%s:stop recording failed rc=%d\n", __func__, rc);
573     }
574 
575     for ( i = 0 ; i < ch->num_streams ; i++ ) {
576         mm_app_del_stream(test_obj, ch, &ch->streams[i]);
577     }
578 
579     mm_app_del_channel(test_obj, ch);
580 
581     return rc;
582 }
583 
mm_app_start_capture(mm_camera_test_obj_t * test_obj,uint8_t num_snapshots)584 int mm_app_start_capture(mm_camera_test_obj_t *test_obj,
585                          uint8_t num_snapshots)
586 {
587     int32_t rc = MM_CAMERA_OK;
588     mm_camera_channel_t *channel = NULL;
589     mm_camera_stream_t *s_main = NULL;
590     mm_camera_stream_t *s_metadata = NULL;
591     mm_camera_channel_attr_t attr;
592 
593     memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
594     attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
595     attr.max_unmatched_frames = 3;
596     channel = mm_app_add_channel(test_obj,
597                                  MM_CHANNEL_TYPE_CAPTURE,
598                                  &attr,
599                                  mm_app_snapshot_notify_cb,
600                                  test_obj);
601     if (NULL == channel) {
602         CDBG_ERROR("%s: add channel failed", __func__);
603         return -MM_CAMERA_E_GENERAL;
604     }
605     s_metadata = mm_app_add_metadata_stream(test_obj,
606                                             channel,
607                                             mm_app_snapshot_metadata_notify_cb,
608                                             (void *)test_obj,
609                                             CAPTURE_BUF_NUM);
610      if (NULL == s_metadata) {
611         CDBG_ERROR("%s: add metadata stream failed\n", __func__);
612         mm_app_del_channel(test_obj, channel);
613         return -MM_CAMERA_E_GENERAL;
614     }
615 
616     s_main = mm_app_add_snapshot_stream(test_obj,
617                                         channel,
618                                         NULL,
619                                         NULL,
620                                         CAPTURE_BUF_NUM,
621                                         num_snapshots);
622     if (NULL == s_main) {
623         CDBG_ERROR("%s: add main snapshot stream failed\n", __func__);
624         mm_app_del_channel(test_obj, channel);
625         return rc;
626     }
627 
628     rc = mm_app_start_channel(test_obj, channel);
629     if (MM_CAMERA_OK != rc) {
630         CDBG_ERROR("%s:start zsl failed rc=%d\n", __func__, rc);
631         mm_app_del_stream(test_obj, channel, s_main);
632         mm_app_del_stream(test_obj, channel, s_metadata);
633         mm_app_del_channel(test_obj, channel);
634         return rc;
635     }
636 
637     return rc;
638 }
639 
mm_app_stop_capture(mm_camera_test_obj_t * test_obj)640 int mm_app_stop_capture(mm_camera_test_obj_t *test_obj)
641 {
642     int rc = MM_CAMERA_OK;
643     mm_camera_channel_t *ch = NULL;
644 
645     ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_CAPTURE);
646 
647     rc = mm_app_stop_and_del_channel(test_obj, ch);
648     if (MM_CAMERA_OK != rc) {
649         CDBG_ERROR("%s:stop capture channel failed rc=%d\n", __func__, rc);
650     }
651 
652     return rc;
653 }
654 
mm_app_take_picture(mm_camera_test_obj_t * test_obj,uint8_t is_burst_mode)655 int mm_app_take_picture(mm_camera_test_obj_t *test_obj, uint8_t is_burst_mode)
656 {
657     CDBG_HIGH("\nEnter %s!!\n",__func__);
658     int rc = MM_CAMERA_OK;
659     int num_snapshot = 1;
660     int num_rcvd_snapshot = 0;
661 
662     if (is_burst_mode)
663        num_snapshot = 6;
664 
665     //stop preview before starting capture.
666     rc = mm_app_stop_preview(test_obj);
667     if (rc != MM_CAMERA_OK) {
668         CDBG_ERROR("%s: stop preview failed before capture!!, err=%d\n",__func__, rc);
669         return rc;
670     }
671 
672     rc = mm_app_start_capture(test_obj, num_snapshot);
673     if (rc != MM_CAMERA_OK) {
674         CDBG_ERROR("%s: mm_app_start_capture(), err=%d\n", __func__,rc);
675         return rc;
676     }
677     while (num_rcvd_snapshot < num_snapshot) {
678         CDBG_HIGH("\nWaiting mm_camera_app_wait !!\n");
679         mm_camera_app_wait();
680         num_rcvd_snapshot++;
681     }
682     rc = mm_app_stop_capture(test_obj);
683     if (rc != MM_CAMERA_OK) {
684        CDBG_ERROR("%s: mm_app_stop_capture(), err=%d\n",__func__, rc);
685        return rc;
686     }
687     //start preview after capture.
688     rc = mm_app_start_preview(test_obj);
689     if (rc != MM_CAMERA_OK) {
690         CDBG_ERROR("%s: start preview failed after capture!!, err=%d\n",__func__,rc);
691     }
692     return rc;
693 }
694