1/* Copyright (c) 2012-2017, 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// Camera dependencies
31#include "mm_qcamera_app.h"
32#include "mm_qcamera_dbg.h"
33
34/* This callback is received once the complete JPEG encoding is done */
35static void jpeg_encode_cb(jpeg_job_status_t status,
36                           uint32_t client_hdl,
37                           uint32_t jobId,
38                           mm_jpeg_output_t *p_buf,
39                           void *userData)
40{
41    uint32_t i = 0;
42    mm_camera_test_obj_t *pme = NULL;
43    LOGD(" BEGIN\n");
44
45    pme = (mm_camera_test_obj_t *)userData;
46    if (pme->jpeg_hdl != client_hdl ||
47        jobId != pme->current_job_id ||
48        !pme->current_job_frames) {
49        LOGE(" NULL current job frames or not matching job ID (%d, %d)",
50                    jobId, pme->current_job_id);
51        return;
52    }
53
54    /* dump jpeg img */
55    LOGE(" job %d, status=%d",  jobId, status);
56    if (status == JPEG_JOB_STATUS_DONE && p_buf != NULL) {
57        mm_app_dump_jpeg_frame(p_buf->buf_vaddr, p_buf->buf_filled_len, "jpeg", "jpg", jobId);
58    }
59
60    /* buf done current encoding frames */
61    pme->current_job_id = 0;
62    for (i = 0; i < pme->current_job_frames->num_bufs; i++) {
63        if (MM_CAMERA_OK != pme->cam->ops->qbuf(pme->current_job_frames->camera_handle,
64                                                pme->current_job_frames->ch_id,
65                                                pme->current_job_frames->bufs[i])) {
66            LOGE(" Failed in Qbuf\n");
67        }
68        mm_app_cache_ops((mm_camera_app_meminfo_t *) pme->current_job_frames->bufs[i]->mem_info,
69                         ION_IOC_INV_CACHES);
70    }
71
72    mm_app_deallocate_ion_memory(&pme->jpeg_buf);
73    free(pme->current_job_frames);
74    pme->current_job_frames = NULL;
75
76    /* signal snapshot is done */
77    mm_camera_app_done();
78}
79
80int encodeData(mm_camera_test_obj_t *test_obj, mm_camera_super_buf_t* recvd_frame,
81               mm_camera_stream_t *m_stream)
82{
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        LOGE(" No memory for current_job_frames");
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
104    /* fill in main src img encode param */
105    job.encode_job.main_dim.src_dim = m_stream->s_config.stream_info->dim;
106    job.encode_job.main_dim.dst_dim = m_stream->s_config.stream_info->dim;
107    job.encode_job.src_index = 0;
108
109    job.encode_job.thumb_dim.src_dim = m_stream->s_config.stream_info->dim;
110    job.encode_job.thumb_dim.dst_dim.width = DEFAULT_PREVIEW_WIDTH;
111    job.encode_job.thumb_dim.dst_dim.height = DEFAULT_PREVIEW_HEIGHT;
112
113    /* fill in sink img param */
114    job.encode_job.dst_index = 0;
115
116    job.encode_job.hal_version = CAM_HAL_V1;
117    test_obj->mExifParams.sensor_params.sens_type = CAM_SENSOR_RAW;
118    job.encode_job.cam_exif_params = test_obj->mExifParams;
119    job.encode_job.cam_exif_params.debug_params =
120            (mm_jpeg_debug_exif_params_t *) malloc (sizeof(mm_jpeg_debug_exif_params_t));
121
122    if (test_obj->mExifParams.debug_params) {
123        memcpy(job.encode_job.cam_exif_params.debug_params,
124            test_obj->mExifParams.debug_params, (sizeof(mm_jpeg_debug_exif_params_t)));
125    }
126
127    job.encode_job.mobicat_mask = 2;
128
129    if (test_obj->metadata != NULL) {
130        job.encode_job.p_metadata = test_obj->metadata;
131    } else {
132        LOGE(" Metadata null, not set for jpeg encoding");
133    }
134
135    if (NULL != job.encode_job.p_metadata && (job.encode_job.mobicat_mask > 0)) {
136
137       if (test_obj->mExifParams.debug_params) {
138           memcpy(job.encode_job.cam_exif_params.debug_params,
139                   test_obj->mExifParams.debug_params, (sizeof(mm_jpeg_debug_exif_params_t)));
140
141           /* Save a copy of mobicat params */
142           job.encode_job.p_metadata->is_mobicat_aec_params_valid =
143                    job.encode_job.cam_exif_params.cam_3a_params_valid;
144
145           if (job.encode_job.cam_exif_params.cam_3a_params_valid) {
146                    job.encode_job.p_metadata->mobicat_aec_params =
147                    job.encode_job.cam_exif_params.cam_3a_params;
148           }
149
150           /* Save a copy of 3A debug params */
151            job.encode_job.p_metadata->is_statsdebug_ae_params_valid =
152                    job.encode_job.cam_exif_params.debug_params->ae_debug_params_valid;
153            job.encode_job.p_metadata->is_statsdebug_awb_params_valid =
154                    job.encode_job.cam_exif_params.debug_params->awb_debug_params_valid;
155            job.encode_job.p_metadata->is_statsdebug_af_params_valid =
156                    job.encode_job.cam_exif_params.debug_params->af_debug_params_valid;
157            job.encode_job.p_metadata->is_statsdebug_asd_params_valid =
158                    job.encode_job.cam_exif_params.debug_params->asd_debug_params_valid;
159            job.encode_job.p_metadata->is_statsdebug_stats_params_valid =
160                    job.encode_job.cam_exif_params.debug_params->stats_debug_params_valid;
161            job.encode_job.p_metadata->is_statsdebug_bestats_params_valid =
162                    job.encode_job.cam_exif_params.debug_params->bestats_debug_params_valid;
163            job.encode_job.p_metadata->is_statsdebug_bhist_params_valid =
164                    job.encode_job.cam_exif_params.debug_params->bhist_debug_params_valid;
165            job.encode_job.p_metadata->is_statsdebug_3a_tuning_params_valid =
166                    job.encode_job.cam_exif_params.debug_params->q3a_tuning_debug_params_valid;
167
168            if (job.encode_job.cam_exif_params.debug_params->ae_debug_params_valid) {
169                job.encode_job.p_metadata->statsdebug_ae_data =
170                        job.encode_job.cam_exif_params.debug_params->ae_debug_params;
171            }
172            if (job.encode_job.cam_exif_params.debug_params->awb_debug_params_valid) {
173                job.encode_job.p_metadata->statsdebug_awb_data =
174                        job.encode_job.cam_exif_params.debug_params->awb_debug_params;
175            }
176            if (job.encode_job.cam_exif_params.debug_params->af_debug_params_valid) {
177                job.encode_job.p_metadata->statsdebug_af_data =
178                        job.encode_job.cam_exif_params.debug_params->af_debug_params;
179            }
180            if (job.encode_job.cam_exif_params.debug_params->asd_debug_params_valid) {
181                job.encode_job.p_metadata->statsdebug_asd_data =
182                        job.encode_job.cam_exif_params.debug_params->asd_debug_params;
183            }
184            if (job.encode_job.cam_exif_params.debug_params->stats_debug_params_valid) {
185                job.encode_job.p_metadata->statsdebug_stats_buffer_data =
186                        job.encode_job.cam_exif_params.debug_params->stats_debug_params;
187            }
188            if (job.encode_job.cam_exif_params.debug_params->bestats_debug_params_valid) {
189                job.encode_job.p_metadata->statsdebug_bestats_buffer_data =
190                        job.encode_job.cam_exif_params.debug_params->bestats_debug_params;
191            }
192            if (job.encode_job.cam_exif_params.debug_params->bhist_debug_params_valid) {
193                job.encode_job.p_metadata->statsdebug_bhist_data =
194                        job.encode_job.cam_exif_params.debug_params->bhist_debug_params;
195            }
196            if (job.encode_job.cam_exif_params.debug_params->q3a_tuning_debug_params_valid) {
197                job.encode_job.p_metadata->statsdebug_3a_tuning_data =
198                        job.encode_job.cam_exif_params.debug_params->q3a_tuning_debug_params;
199            }
200        }
201
202    }
203
204    rc = test_obj->jpeg_ops.start_job(&job, &test_obj->current_job_id);
205    if ( 0 != rc ) {
206        free(test_obj->current_job_frames);
207        test_obj->current_job_frames = NULL;
208    }
209
210    if (job.encode_job.cam_exif_params.debug_params) {
211        free(job.encode_job.cam_exif_params.debug_params);
212    }
213
214    return rc;
215}
216
217int createEncodingSession(mm_camera_test_obj_t *test_obj,
218                          mm_camera_stream_t *m_stream,
219                          mm_camera_buf_def_t *m_frame)
220{
221    mm_jpeg_encode_params_t encode_param;
222
223    memset(&encode_param, 0, sizeof(mm_jpeg_encode_params_t));
224    encode_param.jpeg_cb = jpeg_encode_cb;
225    encode_param.userdata = (void*)test_obj;
226    encode_param.encode_thumbnail = 0;
227    encode_param.quality = 85;
228    encode_param.color_format = MM_JPEG_COLOR_FORMAT_YCRCBLP_H2V2;
229    encode_param.thumb_color_format = MM_JPEG_COLOR_FORMAT_YCRCBLP_H2V2;
230
231    /* fill in main src img encode param */
232    encode_param.num_src_bufs = 1;
233    encode_param.src_main_buf[0].index = 0;
234    encode_param.src_main_buf[0].buf_size = m_frame->frame_len;
235    encode_param.src_main_buf[0].buf_vaddr = (uint8_t *)m_frame->buffer;
236    encode_param.src_main_buf[0].fd = m_frame->fd;
237    encode_param.src_main_buf[0].format = MM_JPEG_FMT_YUV;
238    encode_param.src_main_buf[0].offset = m_stream->offset;
239
240    /* fill in sink img param */
241    encode_param.num_dst_bufs = 1;
242    encode_param.dest_buf[0].index = 0;
243    encode_param.dest_buf[0].buf_size = test_obj->jpeg_buf.mem_info.size;
244    encode_param.dest_buf[0].buf_vaddr = (uint8_t *) test_obj->jpeg_buf.mem_info.data;
245    encode_param.dest_buf[0].fd = test_obj->jpeg_buf.mem_info.fd;
246    encode_param.dest_buf[0].format = MM_JPEG_FMT_YUV;
247
248    /* main dimension */
249    encode_param.main_dim.src_dim = m_stream->s_config.stream_info->dim;
250    encode_param.main_dim.dst_dim = m_stream->s_config.stream_info->dim;
251
252    return test_obj->jpeg_ops.create_session(test_obj->jpeg_hdl,
253                                             &encode_param,
254                                             &test_obj->current_jpeg_sess_id);
255}
256
257/** mm_app_snapshot_metadata_notify_cb
258 *  @bufs: Pointer to super buffer
259 *  @user_data: Pointer to user data
260 *
261 *
262 **/
263__unused
264static void mm_app_snapshot_metadata_notify_cb(mm_camera_super_buf_t *bufs,
265  void *user_data)
266{
267  uint32_t i = 0;
268  mm_camera_channel_t *channel = NULL;
269  mm_camera_stream_t *p_stream = NULL;
270  mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
271  mm_camera_buf_def_t *frame;
272  metadata_buffer_t *pMetadata;
273
274  if (NULL == bufs || NULL == user_data) {
275    LOGE(" bufs or user_data are not valid ");
276    return;
277  }
278  frame = bufs->bufs[0];
279
280  /* find channel */
281  for (i = 0; i < MM_CHANNEL_TYPE_MAX; i++) {
282    if (pme->channels[i].ch_id == bufs->ch_id) {
283      channel = &pme->channels[i];
284      break;
285    }
286  }
287
288  if (NULL == channel) {
289    LOGE(" Channel object is null");
290    return;
291  }
292
293  /* find meta stream */
294  for (i = 0; i < channel->num_streams; i++) {
295    if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_METADATA) {
296      p_stream = &channel->streams[i];
297      break;
298    }
299  }
300
301  if (NULL == p_stream) {
302    LOGE(" cannot find metadata stream");
303    return;
304  }
305
306  /* find meta frame */
307  for (i = 0; i < bufs->num_bufs; i++) {
308    if (bufs->bufs[i]->stream_id == p_stream->s_id) {
309      frame = bufs->bufs[i];
310      break;
311    }
312  }
313
314  if (!pme->metadata) {
315    /* The app will free the metadata, we don't need to bother here */
316    pme->metadata = malloc(sizeof(metadata_buffer_t));
317    if (NULL == pme->metadata) {
318        LOGE(" malloc failed");
319        return;
320    }
321  }
322
323  memcpy(pme->metadata , frame->buffer, sizeof(metadata_buffer_t));
324
325  pMetadata = (metadata_buffer_t *)frame->buffer;
326
327  IF_META_AVAILABLE(cam_auto_focus_data_t, focus_data,
328        CAM_INTF_META_AUTOFOCUS_DATA, pMetadata) {
329    if (focus_data->focus_state == CAM_AF_STATE_FOCUSED_LOCKED) {
330      LOGE(" AutoFocus Done Call Back Received\n");
331      mm_camera_app_done();
332    } else if (focus_data->focus_state == CAM_AF_STATE_NOT_FOCUSED_LOCKED) {
333      LOGE(" AutoFocus failed\n");
334      mm_camera_app_done();
335    }
336  }
337
338  if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
339                                          bufs->ch_id,
340                                          frame)) {
341    LOGE(" Failed in Preview Qbuf\n");
342  }
343  mm_app_cache_ops((mm_camera_app_meminfo_t *)frame->mem_info,
344                   ION_IOC_INV_CACHES);
345}
346
347static void mm_app_snapshot_notify_cb_raw(mm_camera_super_buf_t *bufs,
348                                          void *user_data)
349{
350
351    int rc;
352    uint32_t i = 0;
353    mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
354    mm_camera_channel_t *channel = NULL;
355    mm_camera_stream_t *m_stream = NULL;
356    mm_camera_buf_def_t *m_frame = NULL;
357
358    LOGD(" BEGIN\n");
359
360    /* find channel */
361    for (i = 0; i < MM_CHANNEL_TYPE_MAX; i++) {
362        if (pme->channels[i].ch_id == bufs->ch_id) {
363            channel = &pme->channels[i];
364            break;
365        }
366    }
367    if (NULL == channel) {
368        LOGE(" Wrong channel id (%d)",  bufs->ch_id);
369        rc = -1;
370        goto EXIT;
371    }
372
373    /* find snapshot stream */
374    for (i = 0; i < channel->num_streams; i++) {
375        if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_RAW) {
376            m_stream = &channel->streams[i];
377            break;
378        }
379    }
380    if (NULL == m_stream) {
381        LOGE(" cannot find snapshot stream");
382        rc = -1;
383        goto EXIT;
384    }
385
386    /* find snapshot frame */
387    for (i = 0; i < bufs->num_bufs; i++) {
388        if (bufs->bufs[i]->stream_id == m_stream->s_id) {
389            m_frame = bufs->bufs[i];
390            break;
391        }
392    }
393    if (NULL == m_frame) {
394        LOGE(" main frame is NULL");
395        rc = -1;
396        goto EXIT;
397    }
398
399    mm_app_dump_frame(m_frame, "main", "raw", m_frame->frame_idx);
400
401EXIT:
402    for (i=0; i<bufs->num_bufs; i++) {
403        if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
404                                                bufs->ch_id,
405                                                bufs->bufs[i])) {
406            LOGE(" Failed in Qbuf\n");
407        }
408    }
409
410    mm_camera_app_done();
411
412    LOGD(" END\n");
413}
414
415static void mm_app_snapshot_notify_cb(mm_camera_super_buf_t *bufs,
416                                      void *user_data)
417{
418
419    int rc = 0;
420    uint32_t i = 0;
421    mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
422    mm_camera_channel_t *channel = NULL;
423    mm_camera_stream_t *p_stream = NULL;
424    mm_camera_stream_t *m_stream = NULL;
425    mm_camera_buf_def_t *p_frame = NULL;
426    mm_camera_buf_def_t *m_frame = NULL;
427
428    /* find channel */
429    for (i = 0; i < MM_CHANNEL_TYPE_MAX; i++) {
430        if (pme->channels[i].ch_id == bufs->ch_id) {
431            channel = &pme->channels[i];
432            break;
433        }
434    }
435    if (NULL == channel) {
436        LOGE(" Wrong channel id (%d)",  bufs->ch_id);
437        rc = -1;
438        goto error;
439    }
440
441    /* find snapshot stream */
442    for (i = 0; i < channel->num_streams; i++) {
443        if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_SNAPSHOT) {
444            m_stream = &channel->streams[i];
445            break;
446        }
447    }
448    if (NULL == m_stream) {
449        LOGE(" cannot find snapshot stream");
450        rc = -1;
451        goto error;
452    }
453
454    /* find snapshot frame */
455    for (i = 0; i < bufs->num_bufs; i++) {
456        if (bufs->bufs[i]->stream_id == m_stream->s_id) {
457            m_frame = bufs->bufs[i];
458            break;
459        }
460    }
461    if (NULL == m_frame) {
462        LOGE(" main frame is NULL");
463        rc = -1;
464        goto error;
465    }
466
467    mm_app_dump_frame(m_frame, "main", "yuv", m_frame->frame_idx);
468
469    /* find postview stream */
470    for (i = 0; i < channel->num_streams; i++) {
471        if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_POSTVIEW) {
472            p_stream = &channel->streams[i];
473            break;
474        }
475    }
476    if (NULL != p_stream) {
477        /* find preview frame */
478        for (i = 0; i < bufs->num_bufs; i++) {
479            if (bufs->bufs[i]->stream_id == p_stream->s_id) {
480                p_frame = bufs->bufs[i];
481                break;
482            }
483        }
484        if (NULL != p_frame) {
485            mm_app_dump_frame(p_frame, "postview", "yuv", p_frame->frame_idx);
486        }
487    }
488
489    mm_app_cache_ops((mm_camera_app_meminfo_t *)m_frame->mem_info,
490                     ION_IOC_CLEAN_INV_CACHES);
491
492    pme->jpeg_buf.mem_info.size = m_frame->frame_len;
493
494    mm_app_allocate_ion_memory(&pme->jpeg_buf,
495                              (0x1 << CAMERA_ION_FALLBACK_HEAP_ID));
496
497    /* create a new jpeg encoding session */
498    rc = createEncodingSession(pme, m_stream, m_frame);
499    if (0 != rc) {
500        LOGE(" error creating jpeg session");
501        mm_app_deallocate_ion_memory(&pme->jpeg_buf);
502        goto error;
503    }
504
505    /* start jpeg encoding job */
506    rc = encodeData(pme, bufs, m_stream);
507    if (0 != rc) {
508        LOGE(" error creating jpeg session");
509        mm_app_deallocate_ion_memory(&pme->jpeg_buf);
510        goto error;
511    }
512
513error:
514    /* buf done rcvd frames in error case */
515    if ( 0 != rc ) {
516        for (i=0; i<bufs->num_bufs; i++) {
517            if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
518                                                    bufs->ch_id,
519                                                    bufs->bufs[i])) {
520                LOGE(" Failed in Qbuf\n");
521            }
522            mm_app_cache_ops((mm_camera_app_meminfo_t *)bufs->bufs[i]->mem_info,
523                             ION_IOC_INV_CACHES);
524        }
525    }
526
527    LOGD(" END\n");
528}
529
530mm_camera_channel_t * mm_app_add_snapshot_channel(mm_camera_test_obj_t *test_obj)
531{
532    mm_camera_channel_t *channel = NULL;
533    mm_camera_stream_t *stream = NULL;
534
535    channel = mm_app_add_channel(test_obj,
536                                 MM_CHANNEL_TYPE_SNAPSHOT,
537                                 NULL,
538                                 NULL,
539                                 NULL);
540    if (NULL == channel) {
541        LOGE(" add channel failed");
542        return NULL;
543    }
544
545    stream = mm_app_add_snapshot_stream(test_obj,
546                                        channel,
547                                        mm_app_snapshot_notify_cb,
548                                        (void *)test_obj,
549                                        1,
550                                        1);
551    if (NULL == stream) {
552        LOGE(" add snapshot stream failed\n");
553        mm_app_del_channel(test_obj, channel);
554        return NULL;
555    }
556
557    return channel;
558}
559
560mm_camera_stream_t * mm_app_add_postview_stream(mm_camera_test_obj_t *test_obj,
561                                                mm_camera_channel_t *channel,
562                                                mm_camera_buf_notify_t stream_cb,
563                                                void *userdata,
564                                                uint8_t num_bufs,
565                                                uint8_t num_burst)
566{
567    int rc = MM_CAMERA_OK;
568    mm_camera_stream_t *stream = NULL;
569    cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
570
571    stream = mm_app_add_stream(test_obj, channel);
572    if (NULL == stream) {
573        LOGE(" add stream failed\n");
574        return NULL;
575    }
576
577    stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
578    stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
579    stream->s_config.mem_vtbl.clean_invalidate_buf =
580      mm_app_stream_clean_invalidate_buf;
581    stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
582    stream->s_config.mem_vtbl.clean_buf = mm_app_stream_clean_buf;
583    stream->s_config.mem_vtbl.user_data = (void *)stream;
584    stream->s_config.stream_cb = stream_cb;
585    stream->s_config.stream_cb_sync = NULL;
586    stream->s_config.userdata = userdata;
587    stream->num_of_bufs = num_bufs;
588
589    stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
590    memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
591    stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_POSTVIEW;
592    if (num_burst == 0) {
593        stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
594    } else {
595        stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_BURST;
596        stream->s_config.stream_info->num_of_burst = num_burst;
597    }
598    stream->s_config.stream_info->fmt = DEFAULT_PREVIEW_FORMAT;
599    stream->s_config.stream_info->dim.width = DEFAULT_PREVIEW_WIDTH;
600    stream->s_config.stream_info->dim.height = DEFAULT_PREVIEW_HEIGHT;
601    stream->s_config.stream_info->num_bufs = num_bufs;
602    stream->s_config.padding_info = cam_cap->padding_info;
603
604    rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
605    if (MM_CAMERA_OK != rc) {
606        LOGE("config postview stream err=%d\n",  rc);
607        return NULL;
608    }
609
610    return stream;
611}
612
613int mm_app_start_capture_raw(mm_camera_test_obj_t *test_obj, uint8_t num_snapshots)
614{
615    int32_t rc = MM_CAMERA_OK;
616    mm_camera_channel_t *channel = NULL;
617    mm_camera_stream_t *s_main = NULL;
618    mm_camera_channel_attr_t attr;
619
620    memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
621    attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
622    attr.max_unmatched_frames = 3;
623    channel = mm_app_add_channel(test_obj,
624                                 MM_CHANNEL_TYPE_CAPTURE,
625                                 &attr,
626                                 mm_app_snapshot_notify_cb_raw,
627                                 test_obj);
628    if (NULL == channel) {
629        LOGE(" add channel failed");
630        return -MM_CAMERA_E_GENERAL;
631    }
632
633    test_obj->buffer_format = DEFAULT_RAW_FORMAT;
634    s_main = mm_app_add_raw_stream(test_obj,
635                                   channel,
636                                   mm_app_snapshot_notify_cb_raw,
637                                   test_obj,
638                                   num_snapshots,
639                                   num_snapshots);
640    if (NULL == s_main) {
641        LOGE(" add main snapshot stream failed\n");
642        mm_app_del_channel(test_obj, channel);
643        return rc;
644    }
645
646    rc = mm_app_start_channel(test_obj, channel);
647    if (MM_CAMERA_OK != rc) {
648        LOGE("start zsl failed rc=%d\n",  rc);
649        mm_app_del_stream(test_obj, channel, s_main);
650        mm_app_del_channel(test_obj, channel);
651        return rc;
652    }
653
654    return rc;
655}
656
657int mm_app_stop_capture_raw(mm_camera_test_obj_t *test_obj)
658{
659    int rc = MM_CAMERA_OK;
660    mm_camera_channel_t *ch = NULL;
661    int i;
662    cam_stream_size_info_t abc ;
663    memset (&abc , 0, sizeof (cam_stream_size_info_t));
664
665    ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_CAPTURE);
666
667    rc = mm_app_stop_channel(test_obj, ch);
668    if (MM_CAMERA_OK != rc) {
669        LOGE("stop recording failed rc=%d\n",  rc);
670    }
671
672    for ( i = 0 ; i < ch->num_streams ; i++ ) {
673        mm_app_del_stream(test_obj, ch, &ch->streams[i]);
674    }
675    rc = setmetainfoCommand(test_obj, &abc);
676    if (rc != MM_CAMERA_OK) {
677       LOGE(" meta info command failed\n");
678    }
679    mm_app_del_channel(test_obj, ch);
680
681    return rc;
682}
683
684int mm_app_start_capture(mm_camera_test_obj_t *test_obj,
685                         uint8_t num_snapshots)
686{
687    int32_t rc = MM_CAMERA_OK;
688    mm_camera_channel_t *channel = NULL;
689    mm_camera_stream_t *s_main = NULL;
690    mm_camera_stream_t *s_post = NULL;
691    mm_camera_channel_attr_t attr;
692    memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
693    attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
694    attr.max_unmatched_frames = 3;
695    channel = mm_app_add_channel(test_obj,
696                                 MM_CHANNEL_TYPE_CAPTURE,
697                                 &attr,
698                                 mm_app_snapshot_notify_cb,
699                                 test_obj);
700    if (NULL == channel) {
701        LOGE(" add channel failed");
702        return -MM_CAMERA_E_GENERAL;
703    }
704
705    s_main = mm_app_add_snapshot_stream(test_obj,
706                                        channel,
707                                        mm_app_snapshot_notify_cb,
708                                        (void *)test_obj,
709                                        CAPTURE_BUF_NUM,
710                                        num_snapshots);
711    if (NULL == s_main) {
712        LOGE(" add main snapshot stream failed\n");
713        mm_app_del_channel(test_obj, channel);
714        return rc;
715    }
716
717    s_post = mm_app_add_postview_stream(test_obj,
718                                        channel,
719                                        NULL,
720                                        NULL,
721                                        CAPTURE_BUF_NUM,
722                                        num_snapshots);
723    if (NULL == s_main) {
724        LOGE(" add main postview stream failed\n");
725        mm_app_del_channel(test_obj, channel);
726        return rc;
727    }
728
729    rc = mm_app_start_channel(test_obj, channel);
730    if (MM_CAMERA_OK != rc) {
731        LOGE("start zsl failed rc=%d\n",  rc);
732        mm_app_del_stream(test_obj, channel, s_main);
733        mm_app_del_channel(test_obj, channel);
734        return rc;
735    }
736
737    return rc;
738}
739
740int mm_app_stop_capture(mm_camera_test_obj_t *test_obj)
741{
742    int rc = MM_CAMERA_OK;
743    mm_camera_channel_t *ch = NULL;
744
745    ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_CAPTURE);
746
747    rc = mm_app_stop_and_del_channel(test_obj, ch);
748    if (MM_CAMERA_OK != rc) {
749        LOGE("stop capture channel failed rc=%d\n",  rc);
750    }
751
752    return rc;
753}
754
755int mm_app_take_picture(mm_camera_test_obj_t *test_obj, uint8_t is_burst_mode)
756{
757    LOGH("\nEnter %s!!\n");
758    int rc = MM_CAMERA_OK;
759    uint8_t num_snapshot = 1;
760    int num_rcvd_snapshot = 0;
761
762    if (is_burst_mode)
763       num_snapshot = 6;
764
765    //stop preview before starting capture.
766    rc = mm_app_stop_preview(test_obj);
767    if (rc != MM_CAMERA_OK) {
768        LOGE(" stop preview failed before capture!!, err=%d\n", rc);
769        return rc;
770    }
771
772    rc = mm_app_start_capture(test_obj, num_snapshot);
773    if (rc != MM_CAMERA_OK) {
774        LOGE(" mm_app_start_capture(), err=%d\n", rc);
775        return rc;
776    }
777    while (num_rcvd_snapshot < num_snapshot) {
778        LOGH("\nWaiting mm_camera_app_wait !!\n");
779        mm_camera_app_wait();
780        num_rcvd_snapshot++;
781    }
782    rc = mm_app_stop_capture(test_obj);
783    if (rc != MM_CAMERA_OK) {
784       LOGE(" mm_app_stop_capture(), err=%d\n", rc);
785       return rc;
786    }
787    //start preview after capture.
788    rc = mm_app_start_preview(test_obj);
789    if (rc != MM_CAMERA_OK) {
790        LOGE(" start preview failed after capture!!, err=%d\n",rc);
791    }
792    return rc;
793}
794