1/*
2Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
3
4Redistribution and use in source and binary forms, with or without
5modification, are permitted provided that the following conditions are
6met:
7    * Redistributions of source code must retain the above copyright
8      notice, this list of conditions and the following disclaimer.
9    * Redistributions in binary form must reproduce the above
10      copyright notice, this list of conditions and the following
11      disclaimer in the documentation and/or other materials provided
12      with the distribution.
13    * Neither the name of The Linux Foundation nor the names of its
14      contributors may be used to endorse or promote products derived
15      from this software without specific prior written permission.
16
17THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*/
29
30// System dependencies
31#include <assert.h>
32#include <errno.h>
33#include <fcntl.h>
34#include <sys/ioctl.h>
35#include <unistd.h>
36#define MMAN_H <SYSTEM_HEADER_PREFIX/mman.h>
37#include MMAN_H
38#include <cutils/properties.h>
39
40
41// Camera dependencies
42#include "mm_qcamera_app.h"
43#include "mm_qcamera_dbg.h"
44#include "mm_qcamera_app.h"
45#include <assert.h>
46#include <sys/mman.h>
47#include <semaphore.h>
48
49static void mm_app_metadata_notify_cb(mm_camera_super_buf_t *bufs,
50                                     void *user_data)
51{
52  uint32_t i = 0;
53  mm_camera_channel_t *channel = NULL;
54  mm_camera_stream_t *p_stream = NULL;
55  mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
56  mm_camera_buf_def_t *frame;
57  metadata_buffer_t *pMetadata;
58
59  if (NULL == bufs || NULL == user_data) {
60      LOGE("bufs or user_data are not valid ");
61      return;
62  }
63  frame = bufs->bufs[0];
64
65  /* find channel */
66  for (i = 0; i < MM_CHANNEL_TYPE_MAX; i++) {
67      if (pme->channels[i].ch_id == bufs->ch_id) {
68          channel = &pme->channels[i];
69          break;
70      }
71  }
72
73  if (NULL == channel) {
74      LOGE("Channel object is NULL ");
75      return;
76  }
77
78  /* find preview stream */
79  for (i = 0; i < channel->num_streams; i++) {
80      if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_METADATA) {
81          p_stream = &channel->streams[i];
82          break;
83      }
84  }
85
86  if (NULL == p_stream) {
87      LOGE("cannot find metadata stream");
88      return;
89  }
90
91  /* find preview frame */
92  for (i = 0; i < bufs->num_bufs; i++) {
93      if (bufs->bufs[i]->stream_id == p_stream->s_id) {
94          frame = bufs->bufs[i];
95          break;
96      }
97  }
98
99  if (pme->metadata == NULL) {
100    /* The app will free the meta data, we don't need to bother here */
101    pme->metadata = malloc(sizeof(metadata_buffer_t));
102    if (NULL == pme->metadata) {
103        LOGE("Canot allocate metadata memory\n");
104        return;
105    }
106  }
107
108  memcpy(pme->metadata, frame->buffer, sizeof(metadata_buffer_t));
109
110  pMetadata = (metadata_buffer_t *)frame->buffer;
111
112  IF_META_AVAILABLE(uint32_t, flash_mode, CAM_INTF_META_FLASH_MODE, pMetadata) {
113      pme->mExifParams.sensor_params.flash_mode = (cam_flash_mode_t)*flash_mode;
114  }
115
116  IF_META_AVAILABLE(int32_t, flash_state, CAM_INTF_META_FLASH_STATE, pMetadata) {
117      pme->mExifParams.sensor_params.flash_state = (cam_flash_state_t) *flash_state;
118  }
119
120  IF_META_AVAILABLE(float, aperture_value, CAM_INTF_META_LENS_APERTURE, pMetadata) {
121      pme->mExifParams.sensor_params.aperture_value = *aperture_value;
122  }
123
124
125  IF_META_AVAILABLE(int32_t, wb_mode, CAM_INTF_PARM_WHITE_BALANCE, pMetadata) {
126      pme->mExifParams.cam_3a_params.wb_mode = (cam_wb_mode_type) *wb_mode;
127  }
128
129  IF_META_AVAILABLE(cam_sensor_params_t, sensor_params, CAM_INTF_META_SENSOR_INFO, pMetadata) {
130      pme->mExifParams.sensor_params = *sensor_params;
131  }
132
133  IF_META_AVAILABLE(cam_ae_exif_debug_t, ae_exif_debug_params,
134          CAM_INTF_META_EXIF_DEBUG_AE, pMetadata) {
135      if (pme->mExifParams.debug_params) {
136          pme->mExifParams.debug_params->ae_debug_params = *ae_exif_debug_params;
137          pme->mExifParams.debug_params->ae_debug_params_valid = TRUE;
138
139       }
140
141  }
142
143  IF_META_AVAILABLE(cam_awb_exif_debug_t, awb_exif_debug_params,
144          CAM_INTF_META_EXIF_DEBUG_AWB, pMetadata) {
145      if (pme->mExifParams.debug_params) {
146          pme->mExifParams.debug_params->awb_debug_params = *awb_exif_debug_params;
147          pme->mExifParams.debug_params->awb_debug_params_valid = TRUE;
148          LOGE("Storing AWB Metadata");
149      }
150  }
151
152  IF_META_AVAILABLE(cam_af_exif_debug_t, af_exif_debug_params,
153          CAM_INTF_META_EXIF_DEBUG_AF, pMetadata) {
154      if (pme->mExifParams.debug_params) {
155          pme->mExifParams.debug_params->af_debug_params = *af_exif_debug_params;
156          pme->mExifParams.debug_params->af_debug_params_valid = TRUE;
157      }
158  }
159
160  IF_META_AVAILABLE(cam_asd_exif_debug_t, asd_exif_debug_params,
161          CAM_INTF_META_EXIF_DEBUG_ASD, pMetadata) {
162      if (pme->mExifParams.debug_params) {
163          pme->mExifParams.debug_params->asd_debug_params = *asd_exif_debug_params;
164          pme->mExifParams.debug_params->asd_debug_params_valid = TRUE;
165      }
166  }
167
168  IF_META_AVAILABLE(cam_stats_buffer_exif_debug_t, stats_exif_debug_params,
169          CAM_INTF_META_EXIF_DEBUG_STATS, pMetadata) {
170      if (pme->mExifParams.debug_params) {
171          pme->mExifParams.debug_params->stats_debug_params = *stats_exif_debug_params;
172          pme->mExifParams.debug_params->stats_debug_params_valid = TRUE;
173      }
174  }
175
176  IF_META_AVAILABLE(cam_bestats_buffer_exif_debug_t, bestats_exif_debug_params,
177          CAM_INTF_META_EXIF_DEBUG_BESTATS, pMetadata) {
178      if (pme->mExifParams.debug_params) {
179          pme->mExifParams.debug_params->bestats_debug_params = *bestats_exif_debug_params;
180          pme->mExifParams.debug_params->bestats_debug_params_valid = TRUE;
181      }
182  }
183
184  IF_META_AVAILABLE(cam_bhist_buffer_exif_debug_t, bhist_exif_debug_params,
185          CAM_INTF_META_EXIF_DEBUG_BHIST, pMetadata) {
186      if (pme->mExifParams.debug_params) {
187          pme->mExifParams.debug_params->bhist_debug_params = *bhist_exif_debug_params;
188          pme->mExifParams.debug_params->bhist_debug_params_valid = TRUE;
189      }
190  }
191
192  IF_META_AVAILABLE(cam_q3a_tuning_info_t, q3a_tuning_exif_debug_params,
193          CAM_INTF_META_EXIF_DEBUG_3A_TUNING, pMetadata) {
194      if (pme->mExifParams.debug_params) {
195          pme->mExifParams.debug_params->q3a_tuning_debug_params = *q3a_tuning_exif_debug_params;
196          pme->mExifParams.debug_params->q3a_tuning_debug_params_valid = TRUE;
197      }
198  }
199  IF_META_AVAILABLE(uint32_t, afState, CAM_INTF_META_AF_STATE, pMetadata) {
200    if ((cam_af_state_t)(*afState) == CAM_AF_STATE_FOCUSED_LOCKED ||
201            (cam_af_state_t)(*afState) == CAM_AF_STATE_NOT_FOCUSED_LOCKED) {
202        LOGE("AutoFocus Done Call Back Received\n");
203        mm_camera_app_done();
204    } else if ((cam_af_state_t)(*afState) == CAM_AF_STATE_NOT_FOCUSED_LOCKED) {
205        LOGE("AutoFocus failed\n");
206        mm_camera_app_done();
207    }
208  }
209
210  if (pme->user_metadata_cb) {
211      LOGD("[DBG] user defined own metadata cb. calling it...");
212      pme->user_metadata_cb(frame);
213  }
214
215  if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
216                                          bufs->ch_id,
217                                          frame)) {
218      LOGE("Failed in Preview Qbuf\n");
219  }
220  mm_app_cache_ops((mm_camera_app_meminfo_t *)frame->mem_info,
221                   ION_IOC_INV_CACHES);
222}
223
224static void mm_app_snapshot_notify_cb(mm_camera_super_buf_t *bufs,
225                                      void *user_data)
226{
227
228    int rc = 0;
229    uint32_t i = 0;
230    mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
231    mm_camera_channel_t *channel = NULL;
232    mm_camera_stream_t *p_stream = NULL;
233    mm_camera_stream_t *m_stream = NULL;
234    mm_camera_buf_def_t *p_frame = NULL;
235    mm_camera_buf_def_t *m_frame = NULL;
236
237    /* find channel */
238    for (i = 0; i < MM_CHANNEL_TYPE_MAX; i++) {
239        if (pme->channels[i].ch_id == bufs->ch_id) {
240            channel = &pme->channels[i];
241            break;
242        }
243    }
244    if (NULL == channel) {
245        LOGE("Wrong channel id (%d)",  bufs->ch_id);
246        rc = -1;
247        goto error;
248    }
249
250    /* find snapshot stream */
251    for (i = 0; i < channel->num_streams; i++) {
252        if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_SNAPSHOT) {
253            m_stream = &channel->streams[i];
254            break;
255        }
256    }
257    if (NULL == m_stream) {
258        LOGE("cannot find snapshot stream");
259        rc = -1;
260        goto error;
261    }
262
263    /* find snapshot frame */
264    for (i = 0; i < bufs->num_bufs; i++) {
265        if (bufs->bufs[i]->stream_id == m_stream->s_id) {
266            m_frame = bufs->bufs[i];
267            break;
268        }
269    }
270    if (NULL == m_frame) {
271        LOGE("main frame is NULL");
272        rc = -1;
273        goto error;
274    }
275
276    mm_app_dump_frame(m_frame, "main", "yuv", m_frame->frame_idx);
277
278    /* find postview stream */
279    for (i = 0; i < channel->num_streams; i++) {
280        if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_POSTVIEW) {
281            p_stream = &channel->streams[i];
282            break;
283        }
284    }
285    if (NULL != p_stream) {
286        /* find preview frame */
287        for (i = 0; i < bufs->num_bufs; i++) {
288            if (bufs->bufs[i]->stream_id == p_stream->s_id) {
289                p_frame = bufs->bufs[i];
290                break;
291            }
292        }
293        if (NULL != p_frame) {
294            mm_app_dump_frame(p_frame, "postview", "yuv", p_frame->frame_idx);
295        }
296    }
297
298    mm_app_cache_ops((mm_camera_app_meminfo_t *)m_frame->mem_info,
299                     ION_IOC_CLEAN_INV_CACHES);
300
301    pme->jpeg_buf.buf.buffer = (uint8_t *)malloc(m_frame->frame_len);
302    if ( NULL == pme->jpeg_buf.buf.buffer ) {
303        LOGE("error allocating jpeg output buffer");
304        goto error;
305    }
306
307    pme->jpeg_buf.buf.frame_len = m_frame->frame_len;
308    /* create a new jpeg encoding session */
309    rc = createEncodingSession(pme, m_stream, m_frame);
310    if (0 != rc) {
311        LOGE("error creating jpeg session");
312        free(pme->jpeg_buf.buf.buffer);
313        goto error;
314    }
315
316    /* start jpeg encoding job */
317    rc = encodeData(pme, bufs, m_stream);
318    if (0 != rc) {
319        LOGE("error creating jpeg session");
320        free(pme->jpeg_buf.buf.buffer);
321        goto error;
322    }
323
324error:
325    /* buf done rcvd frames in error case */
326    if ( 0 != rc ) {
327        for (i=0; i<bufs->num_bufs; i++) {
328            if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
329                                                    bufs->ch_id,
330                                                    bufs->bufs[i])) {
331                LOGE("Failed in Qbuf\n");
332            }
333            mm_app_cache_ops((mm_camera_app_meminfo_t *)bufs->bufs[i]->mem_info,
334                             ION_IOC_INV_CACHES);
335        }
336    }
337
338    LOGD(" END\n");
339}
340
341static void mm_app_preview_notify_cb(mm_camera_super_buf_t *bufs,
342                                     void *user_data)
343{
344    uint32_t i = 0;
345    char value[PROPERTY_VALUE_MAX];
346    mm_camera_channel_t *channel = NULL;
347    mm_camera_stream_t *p_stream = NULL;
348    mm_camera_buf_def_t *frame = NULL;
349    mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
350    property_get("persist.camera.dumpimg", value, "0");
351    uint32_t dump_preview = (uint32_t) atoi(value);
352
353    if (NULL == bufs || NULL == user_data) {
354        LOGE("bufs or user_data are not valid ");
355        return;
356    }
357
358    frame = bufs->bufs[0];
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("Channel object is NULL ");
369        return;
370    }
371    /* find preview stream */
372    for (i = 0; i < channel->num_streams; i++) {
373        if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_PREVIEW) {
374            p_stream = &channel->streams[i];
375            break;
376        }
377    }
378
379    if (NULL == p_stream) {
380        LOGE("cannot find preview stream");
381        return;
382    }
383
384    /* find preview frame */
385    for (i = 0; i < bufs->num_bufs; i++) {
386        if (bufs->bufs[i]->stream_id == p_stream->s_id) {
387            frame = bufs->bufs[i];
388            break;
389        }
390    }
391
392    if ( 0 < pme->fb_fd ) {
393        mm_app_overlay_display(pme, frame->fd);
394    }
395
396    if (dump_preview & QCAMERA_DUMP_FRM_PREVIEW) {
397        char file_name[64];
398        snprintf(file_name, sizeof(file_name), "P_C%d", pme->cam->camera_handle);
399        mm_app_dump_frame(frame, file_name, "yuv", frame->frame_idx);
400    }
401
402    if (pme->user_preview_cb) {
403        LOGD("[DBG]user defined own preview cb. calling it...");
404        pme->user_preview_cb(frame);
405    }
406    if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
407                bufs->ch_id,
408                frame)) {
409        LOGE("Failed in Preview Qbuf\n");
410    }
411    mm_app_cache_ops((mm_camera_app_meminfo_t *)frame->mem_info,
412            ION_IOC_INV_CACHES);
413
414    LOGD(" END\n");
415}
416
417static void mm_app_zsl_notify_cb(mm_camera_super_buf_t *bufs,
418                                 void *user_data)
419{
420    int rc = MM_CAMERA_OK;
421    uint32_t i = 0;
422    mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
423    mm_camera_channel_t *channel = NULL;
424    mm_camera_stream_t *p_stream = NULL;
425    mm_camera_stream_t *m_stream = NULL;
426    mm_camera_stream_t *md_stream = NULL;
427    mm_camera_buf_def_t *p_frame = NULL;
428    mm_camera_buf_def_t *m_frame = NULL;
429    mm_camera_buf_def_t *md_frame = NULL;
430
431    LOGD(" BEGIN\n");
432
433    if (NULL == bufs || NULL == user_data) {
434        LOGE("bufs or user_data are not valid ");
435        return;
436    }
437
438    /* find channel */
439    for (i = 0; i < MM_CHANNEL_TYPE_MAX; i++) {
440        if (pme->channels[i].ch_id == bufs->ch_id) {
441            channel = &pme->channels[i];
442            break;
443        }
444    }
445    if (NULL == channel) {
446        LOGE("Wrong channel id (%d)",  bufs->ch_id);
447        return;
448    }
449
450    /* find preview stream */
451    for (i = 0; i < channel->num_streams; i++) {
452        if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_PREVIEW) {
453            p_stream = &channel->streams[i];
454            break;
455        }
456    }
457    if (NULL == p_stream) {
458        LOGE("cannot find preview stream");
459        return;
460    }
461
462    /* find snapshot stream */
463    for (i = 0; i < channel->num_streams; i++) {
464        if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_SNAPSHOT) {
465            m_stream = &channel->streams[i];
466            break;
467        }
468    }
469    if (NULL == m_stream) {
470        LOGE("cannot find snapshot stream");
471        return;
472    }
473
474    /* find metadata stream */
475    for (i = 0; i < channel->num_streams; i++) {
476        if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_METADATA) {
477            md_stream = &channel->streams[i];
478            break;
479        }
480    }
481    if (NULL == md_stream) {
482        LOGE("cannot find metadata stream");
483    }
484
485    /* find preview frame */
486    for (i = 0; i < bufs->num_bufs; i++) {
487        if (bufs->bufs[i]->stream_id == p_stream->s_id) {
488            p_frame = bufs->bufs[i];
489            break;
490        }
491    }
492
493    if(md_stream) {
494      /* find metadata frame */
495      for (i = 0; i < bufs->num_bufs; i++) {
496          if (bufs->bufs[i]->stream_id == md_stream->s_id) {
497              md_frame = bufs->bufs[i];
498              break;
499          }
500      }
501      if (!md_frame) {
502          LOGE("md_frame is null\n");
503          return;
504      }
505      if (!pme->metadata) {
506          /* App will free the metadata */
507          pme->metadata = malloc(sizeof(metadata_buffer_t));
508          if (!pme->metadata) {
509              ALOGE("not enough memory\n");
510              return;
511          }
512      }
513
514      memcpy(pme->metadata , md_frame->buffer, sizeof(metadata_buffer_t));
515    }
516    /* find snapshot frame */
517    for (i = 0; i < bufs->num_bufs; i++) {
518        if (bufs->bufs[i]->stream_id == m_stream->s_id) {
519            m_frame = bufs->bufs[i];
520            break;
521        }
522    }
523
524    if (!m_frame || !p_frame) {
525        LOGE("cannot find preview/snapshot frame");
526        return;
527    }
528
529    LOGD(" ZSL CB with fb_fd = %d, m_frame = %p, p_frame = %p \n",
530         pme->fb_fd,
531         m_frame,
532         p_frame);
533
534    if ( 0 < pme->fb_fd ) {
535        mm_app_overlay_display(pme, p_frame->fd);
536    }/* else {
537        mm_app_dump_frame(p_frame, "zsl_preview", "yuv", p_frame->frame_idx);
538        mm_app_dump_frame(m_frame, "zsl_main", "yuv", m_frame->frame_idx);
539    }*/
540
541    if ( pme->flip_mode ) {
542        int32_t prmFlip = pme->flip_mode;
543        if (md_frame) {
544            metadata_buffer_t* md_data = (metadata_buffer_t*)(md_frame->buffer);
545            ADD_SET_PARAM_ENTRY_TO_BATCH(md_data, CAM_INTF_PARM_FLIP, prmFlip);
546        }
547    }
548
549    if ( pme->enable_reproc && ( NULL != pme->reproc_stream ) ) {
550
551
552        if (NULL != md_frame) {
553            rc = mm_app_do_reprocess(pme,
554                    m_frame,
555                    md_frame->buf_idx,
556                    bufs,
557                    md_stream);
558
559            if (MM_CAMERA_OK != rc ) {
560                LOGE("reprocess failed rc = %d",  rc);
561            }
562        } else {
563            LOGE("md_frame is null\n");
564        }
565
566      return;
567    }
568
569    if ( pme->encodeJpeg ) {
570        pme->jpeg_buf.buf.buffer = (uint8_t *)malloc(m_frame->frame_len);
571        if ( NULL == pme->jpeg_buf.buf.buffer ) {
572            LOGE("error allocating jpeg output buffer");
573            goto exit;
574        }
575
576        pme->jpeg_buf.buf.frame_len = m_frame->frame_len;
577        /* create a new jpeg encoding session */
578        rc = createEncodingSession(pme, m_stream, m_frame);
579        if (0 != rc) {
580            LOGE("error creating jpeg session");
581            free(pme->jpeg_buf.buf.buffer);
582            goto exit;
583        }
584
585        /* start jpeg encoding job */
586        rc = encodeData(pme, bufs, m_stream);
587        pme->encodeJpeg = 0;
588    } else {
589        if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
590                                                bufs->ch_id,
591                                                m_frame)) {
592            LOGE("Failed in main Qbuf\n");
593        }
594        mm_app_cache_ops((mm_camera_app_meminfo_t *)m_frame->mem_info,
595                         ION_IOC_INV_CACHES);
596    }
597
598exit:
599
600    if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
601                                            bufs->ch_id,
602                                            p_frame)) {
603        LOGE("Failed in preview Qbuf\n");
604    }
605    mm_app_cache_ops((mm_camera_app_meminfo_t *)p_frame->mem_info,
606                     ION_IOC_INV_CACHES);
607
608    if(md_frame) {
609      if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
610                                              bufs->ch_id,
611                                              md_frame)) {
612          LOGE("Failed in metadata Qbuf\n");
613      }
614      mm_app_cache_ops((mm_camera_app_meminfo_t *)md_frame->mem_info,
615                       ION_IOC_INV_CACHES);
616    }
617
618    LOGD(" END\n");
619}
620
621mm_camera_stream_t * mm_app_add_metadata_stream(mm_camera_test_obj_t *test_obj,
622                                               mm_camera_channel_t *channel,
623                                               mm_camera_buf_notify_t stream_cb,
624                                               void *userdata,
625                                               uint8_t num_bufs)
626{
627    int rc = MM_CAMERA_OK;
628    mm_camera_stream_t *stream = NULL;
629    cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
630    stream = mm_app_add_stream(test_obj, channel);
631    if (NULL == stream) {
632        LOGE("add stream failed\n");
633        return NULL;
634    }
635
636    stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
637    stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
638    stream->s_config.mem_vtbl.clean_invalidate_buf =
639      mm_app_stream_clean_invalidate_buf;
640    stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
641    stream->s_config.mem_vtbl.clean_buf = mm_app_stream_clean_buf;
642    stream->s_config.mem_vtbl.user_data = (void *)stream;
643    stream->s_config.stream_cb = stream_cb;
644    stream->s_config.stream_cb_sync = NULL;
645    stream->s_config.userdata = userdata;
646    stream->num_of_bufs = num_bufs;
647
648    stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
649    memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
650    stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_METADATA;
651    stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
652    stream->s_config.stream_info->fmt = DEFAULT_PREVIEW_FORMAT;
653    stream->s_config.stream_info->dim.width = sizeof(metadata_buffer_t);
654    stream->s_config.stream_info->dim.height = 1;
655    stream->s_config.stream_info->num_bufs = num_bufs;
656    stream->s_config.padding_info = cam_cap->padding_info;
657
658    rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
659    if (MM_CAMERA_OK != rc) {
660        LOGE("config preview stream err=%d\n",  rc);
661        return NULL;
662    }
663
664    return stream;
665}
666
667cam_dimension_t mm_app_get_analysis_stream_dim(
668                                               const mm_camera_test_obj_t *test_obj,
669                                               const cam_dimension_t* preview_dim)
670{
671    cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
672    cam_dimension_t max_analysis_dim =
673        cam_cap->analysis_info[CAM_ANALYSIS_INFO_FD_STILL].analysis_max_res;
674    cam_dimension_t analysis_dim = {0, 0};
675
676    if (preview_dim->width > max_analysis_dim.width ||
677            preview_dim->height > max_analysis_dim.height) {
678        double max_ratio, requested_ratio;
679
680        max_ratio = (double)max_analysis_dim.width / (double)max_analysis_dim.height;
681        requested_ratio = (double)preview_dim->width / (double)preview_dim->height;
682
683        if (max_ratio < requested_ratio) {
684            analysis_dim.width = max_analysis_dim.width;
685            analysis_dim.height = (int32_t)((double)max_analysis_dim.width / requested_ratio);
686        } else {
687            analysis_dim.height = max_analysis_dim.height;
688            analysis_dim.width = (int32_t)((double)max_analysis_dim.height * requested_ratio);
689        }
690        analysis_dim.width &= ~0x1;
691        analysis_dim.height &= ~0x1;
692    } else {
693        analysis_dim = *preview_dim;
694    }
695
696    LOGI("analysis stream dim (%d x %d)\n",  analysis_dim.width, analysis_dim.height);
697    return analysis_dim;
698}
699
700mm_camera_stream_t * mm_app_add_analysis_stream(mm_camera_test_obj_t *test_obj,
701                                               mm_camera_channel_t *channel,
702                                               mm_camera_buf_notify_t stream_cb,
703                                               void *userdata,
704                                               uint8_t num_bufs)
705{
706    int rc = MM_CAMERA_OK;
707    mm_camera_stream_t *stream = NULL;
708    cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
709    cam_dimension_t preview_dim = {0, 0};
710    cam_dimension_t analysis_dim = {0, 0};
711
712    if ((test_obj->preview_resolution.user_input_display_width == 0) ||
713           ( test_obj->preview_resolution.user_input_display_height == 0)) {
714        preview_dim.width = DEFAULT_PREVIEW_WIDTH;
715        preview_dim.height = DEFAULT_PREVIEW_HEIGHT;
716    } else {
717        preview_dim.width = test_obj->preview_resolution.user_input_display_width;
718        preview_dim.height = test_obj->preview_resolution.user_input_display_height;
719    }
720
721    analysis_dim = mm_app_get_analysis_stream_dim(test_obj, &preview_dim);
722    LOGI("analysis stream dimesion: %d x %d\n",
723            analysis_dim.width, analysis_dim.height);
724    if (analysis_dim.width == 0 || analysis_dim.height == 0) {
725        /* FD or PAAF might not be enabled , use preview dim */
726        return NULL;
727    }
728
729    stream = mm_app_add_stream(test_obj, channel);
730    if (NULL == stream) {
731        LOGE("add stream failed\n");
732        return NULL;
733    }
734
735    stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
736    stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
737    stream->s_config.mem_vtbl.clean_invalidate_buf =
738      mm_app_stream_clean_invalidate_buf;
739    stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
740    stream->s_config.mem_vtbl.clean_buf = mm_app_stream_clean_buf;
741    stream->s_config.mem_vtbl.user_data = (void *)stream;
742    stream->s_config.stream_cb = stream_cb;
743    stream->s_config.userdata = userdata;
744    stream->num_of_bufs = num_bufs;
745
746    stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
747    memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
748    stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_ANALYSIS;
749    stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
750    stream->s_config.stream_info->fmt = DEFAULT_PREVIEW_FORMAT;
751    stream->s_config.stream_info->dim = analysis_dim;
752    stream->s_config.padding_info =
753        cam_cap->analysis_info[CAM_ANALYSIS_INFO_FD_STILL].analysis_padding_info;
754    stream->s_config.stream_info->num_bufs = num_bufs;
755
756    rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
757    if (MM_CAMERA_OK != rc) {
758        LOGE("config preview stream err=%d\n",  rc);
759        return NULL;
760    }
761
762    return stream;
763}
764mm_camera_stream_t * mm_app_add_ZSL_preview_stream(mm_camera_test_obj_t *test_obj,
765                                               mm_camera_channel_t *channel,
766                                               mm_camera_buf_notify_t stream_cb,
767                                               void *userdata,
768                                               uint8_t num_bufs)
769{
770    int rc = MM_CAMERA_OK;
771    mm_camera_stream_t *stream = NULL;
772    cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
773    cam_dimension_t preview_dim = {0, 0};
774    cam_dimension_t analysis_dim = {0, 0};
775
776    if ((test_obj->preview_resolution.user_input_display_width == 0) ||
777           ( test_obj->preview_resolution.user_input_display_height == 0)) {
778        preview_dim.width = DEFAULT_PREVIEW_WIDTH;
779        preview_dim.height = DEFAULT_PREVIEW_HEIGHT;
780    } else {
781        preview_dim.width = test_obj->preview_resolution.user_input_display_width;
782        preview_dim.height = test_obj->preview_resolution.user_input_display_height;
783    }
784    LOGI("preview dimesion: %d x %d\n",  preview_dim.width, preview_dim.height);
785
786    analysis_dim = mm_app_get_analysis_stream_dim(test_obj, &preview_dim);
787    LOGI("analysis stream dimesion: %d x %d\n",
788            analysis_dim.width, analysis_dim.height);
789
790    uint32_t analysis_pp_mask = cam_cap->qcom_supported_feature_mask &
791                                        (CAM_QCOM_FEATURE_SHARPNESS |
792                                         CAM_QCOM_FEATURE_EFFECT |
793                                         CAM_QCOM_FEATURE_DENOISE2D);
794    LOGI("analysis stream pp mask:%x\n",  analysis_pp_mask);
795
796    stream = mm_app_add_stream(test_obj, channel);
797    if (NULL == stream) {
798        LOGE("add stream failed\n");
799        return NULL;
800    }
801    stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
802    stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
803    stream->s_config.mem_vtbl.clean_invalidate_buf =
804      mm_app_stream_clean_invalidate_buf;
805    stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
806    stream->s_config.mem_vtbl.clean_buf = mm_app_stream_clean_buf;
807    stream->s_config.mem_vtbl.user_data = (void *)stream;
808    stream->s_config.stream_cb = stream_cb;
809    stream->s_config.stream_cb_sync = NULL;
810    stream->s_config.userdata = userdata;
811    stream->num_of_bufs = num_bufs;
812
813    stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
814    memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
815    stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_PREVIEW;
816    stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
817    stream->s_config.stream_info->fmt = DEFAULT_PREVIEW_FORMAT;
818
819    stream->s_config.stream_info->dim.width = preview_dim.width;
820    stream->s_config.stream_info->dim.height = preview_dim.height;
821    stream->s_config.stream_info->num_bufs = num_bufs;
822    stream->s_config.padding_info = cam_cap->padding_info;
823
824    rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
825    if (MM_CAMERA_OK != rc) {
826        LOGE("config preview stream err=%d\n",  rc);
827        return NULL;
828    }
829
830    return stream;
831}
832
833
834mm_camera_stream_t * mm_app_add_preview_stream(mm_camera_test_obj_t *test_obj,
835                                               mm_camera_channel_t *channel,
836                                               mm_camera_buf_notify_t stream_cb,
837                                               void *userdata,
838                                               uint8_t num_bufs)
839{
840    int rc = MM_CAMERA_OK;
841    mm_camera_stream_t *stream = NULL;
842    cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
843    cam_dimension_t preview_dim = {0, 0};
844    cam_dimension_t analysis_dim = {0, 0};
845
846    if ((test_obj->preview_resolution.user_input_display_width == 0) ||
847           ( test_obj->preview_resolution.user_input_display_height == 0)) {
848        preview_dim.width = DEFAULT_PREVIEW_WIDTH;
849        preview_dim.height = DEFAULT_PREVIEW_HEIGHT;
850    } else {
851        preview_dim.width = test_obj->preview_resolution.user_input_display_width;
852        preview_dim.height = test_obj->preview_resolution.user_input_display_height;
853    }
854    LOGI("preview dimesion: %d x %d\n",  preview_dim.width, preview_dim.height);
855
856    analysis_dim = mm_app_get_analysis_stream_dim(test_obj, &preview_dim);
857    LOGI("analysis stream dimesion: %d x %d\n",
858            analysis_dim.width, analysis_dim.height);
859
860    uint32_t analysis_pp_mask = cam_cap->qcom_supported_feature_mask &
861                                        (CAM_QCOM_FEATURE_SHARPNESS |
862                                         CAM_QCOM_FEATURE_EFFECT |
863                                         CAM_QCOM_FEATURE_DENOISE2D);
864    LOGI("analysis stream pp mask:%x\n",  analysis_pp_mask);
865
866    cam_stream_size_info_t abc ;
867    memset (&abc , 0, sizeof (cam_stream_size_info_t));
868
869    if (analysis_dim.width != 0 && analysis_dim.height != 0) {
870      abc.num_streams = 2;
871    } else {
872      abc.num_streams = 1;
873    }
874    abc.postprocess_mask[0] = 2178;
875    abc.stream_sizes[0].width = preview_dim.width;
876    abc.stream_sizes[0].height = preview_dim.height;
877    abc.type[0] = CAM_STREAM_TYPE_PREVIEW;
878
879    if (analysis_dim.width != 0 && analysis_dim.height != 0) {
880      abc.postprocess_mask[1] = analysis_pp_mask;
881      abc.stream_sizes[1].width = analysis_dim.width;
882      abc.stream_sizes[1].height = analysis_dim.height;
883      abc.type[1] = CAM_STREAM_TYPE_ANALYSIS;
884    }
885
886    abc.buffer_info.min_buffers = 10;
887    abc.buffer_info.max_buffers = 10;
888    abc.is_type[0] = IS_TYPE_NONE;
889
890    rc = setmetainfoCommand(test_obj, &abc);
891    if (rc != MM_CAMERA_OK) {
892       LOGE("meta info command failed\n");
893    }
894
895    stream = mm_app_add_stream(test_obj, channel);
896    if (NULL == stream) {
897        LOGE("add stream failed\n");
898        return NULL;
899    }
900    stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
901    stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
902    stream->s_config.mem_vtbl.clean_invalidate_buf =
903      mm_app_stream_clean_invalidate_buf;
904    stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
905    stream->s_config.mem_vtbl.clean_buf = mm_app_stream_clean_buf;
906    stream->s_config.mem_vtbl.user_data = (void *)stream;
907    stream->s_config.stream_cb = stream_cb;
908    stream->s_config.stream_cb_sync = NULL;
909    stream->s_config.userdata = userdata;
910    stream->num_of_bufs = num_bufs;
911
912    stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
913    memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
914    stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_PREVIEW;
915    stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
916    stream->s_config.stream_info->fmt = DEFAULT_PREVIEW_FORMAT;
917
918    if (test_obj->enable_EZTune) {
919        stream->s_config.stream_info->pp_config.feature_mask = CAM_QCOM_FEATURE_EZTUNE;
920    }
921
922    stream->s_config.stream_info->dim.width = preview_dim.width;
923    stream->s_config.stream_info->dim.height = preview_dim.height;
924    stream->s_config.stream_info->num_bufs = num_bufs;
925    stream->s_config.padding_info = cam_cap->padding_info;
926
927    rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
928    if (MM_CAMERA_OK != rc) {
929        LOGE("config preview stream err=%d\n",  rc);
930        return NULL;
931    }
932
933    return stream;
934}
935
936mm_camera_stream_t * mm_app_add_raw_stream(mm_camera_test_obj_t *test_obj,
937                                                mm_camera_channel_t *channel,
938                                                mm_camera_buf_notify_t stream_cb,
939                                                void *userdata,
940                                                uint8_t num_bufs,
941                                                uint8_t num_burst)
942{
943    int rc = MM_CAMERA_OK;
944    mm_camera_stream_t *stream = NULL;
945    cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
946
947    cam_stream_size_info_t abc ;
948    memset (&abc , 0, sizeof (cam_stream_size_info_t));
949
950    abc.num_streams = 1;
951    abc.postprocess_mask[0] = 0;
952
953    if ( test_obj->buffer_width == 0 || test_obj->buffer_height == 0 ) {
954        abc.stream_sizes[0].width = DEFAULT_SNAPSHOT_WIDTH;
955        abc.stream_sizes[0].height = DEFAULT_SNAPSHOT_HEIGHT;
956    } else {
957        abc.stream_sizes[0].width = (int32_t)test_obj->buffer_width;
958        abc.stream_sizes[0].height = (int32_t)test_obj->buffer_height;
959    }
960    abc.type[0] = CAM_STREAM_TYPE_RAW;
961
962    abc.buffer_info.min_buffers = num_bufs;
963    abc.buffer_info.max_buffers = num_bufs;
964    abc.is_type[0] = IS_TYPE_NONE;
965
966    rc = setmetainfoCommand(test_obj, &abc);
967    if (rc != MM_CAMERA_OK) {
968       LOGE("meta info command failed\n");
969    }
970
971    stream = mm_app_add_stream(test_obj, channel);
972    if (NULL == stream) {
973        LOGE("add stream failed\n");
974        return NULL;
975    }
976
977    stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
978    stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
979    stream->s_config.mem_vtbl.clean_invalidate_buf =
980      mm_app_stream_clean_invalidate_buf;
981    stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
982    stream->s_config.mem_vtbl.clean_buf = mm_app_stream_clean_buf;
983    stream->s_config.mem_vtbl.user_data = (void *)stream;
984    stream->s_config.stream_cb = stream_cb;
985    stream->s_config.stream_cb_sync = NULL;
986    stream->s_config.userdata = userdata;
987    stream->num_of_bufs = num_bufs;
988
989    stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
990    memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
991    stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_RAW;
992    if (num_burst == 0) {
993        stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
994    } else {
995        stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_BURST;
996        stream->s_config.stream_info->num_of_burst = num_burst;
997    }
998    stream->s_config.stream_info->fmt = test_obj->buffer_format;
999    if ( test_obj->buffer_width == 0 || test_obj->buffer_height == 0 ) {
1000        stream->s_config.stream_info->dim.width = DEFAULT_SNAPSHOT_WIDTH;
1001        stream->s_config.stream_info->dim.height = DEFAULT_SNAPSHOT_HEIGHT;
1002    } else {
1003        stream->s_config.stream_info->dim.width = (int32_t)test_obj->buffer_width;
1004        stream->s_config.stream_info->dim.height = (int32_t)test_obj->buffer_height;
1005    }
1006    stream->s_config.stream_info->num_bufs = num_bufs;
1007    stream->s_config.padding_info = cam_cap->padding_info;
1008
1009    rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
1010    if (MM_CAMERA_OK != rc) {
1011        LOGE("config preview stream err=%d\n",  rc);
1012        return NULL;
1013    }
1014
1015    return stream;
1016}
1017
1018mm_camera_stream_t * mm_app_add_ZSL_snapshot_stream(mm_camera_test_obj_t *test_obj,
1019                                                mm_camera_channel_t *channel,
1020                                                mm_camera_buf_notify_t stream_cb,
1021                                                void *userdata,
1022                                                uint8_t num_bufs,
1023                                                uint8_t num_burst)
1024{
1025  int rc = MM_CAMERA_OK;
1026    mm_camera_stream_t *stream = NULL;
1027    cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
1028    cam_stream_size_info_t abc_snap ;
1029    memset (&abc_snap , 0, sizeof (cam_stream_size_info_t));
1030
1031    abc_snap.num_streams = 2;
1032    abc_snap.postprocess_mask[1] = 2178;
1033    abc_snap.stream_sizes[1].width = DEFAULT_PREVIEW_WIDTH;
1034    abc_snap.stream_sizes[1].height = DEFAULT_PREVIEW_HEIGHT;
1035    abc_snap.type[1] = CAM_STREAM_TYPE_PREVIEW;
1036
1037    abc_snap.postprocess_mask[0] = 0;
1038    if ( test_obj->buffer_width == 0 || test_obj->buffer_height == 0 ) {
1039        abc_snap.stream_sizes[0].width = DEFAULT_SNAPSHOT_WIDTH;
1040        abc_snap.stream_sizes[0].height = DEFAULT_SNAPSHOT_HEIGHT;
1041    } else {
1042        abc_snap.stream_sizes[0].width = test_obj->buffer_width;
1043        abc_snap.stream_sizes[0].height = test_obj->buffer_height;
1044    }
1045    abc_snap.type[0] = CAM_STREAM_TYPE_SNAPSHOT;
1046
1047    abc_snap.buffer_info.min_buffers = 7;
1048    abc_snap.buffer_info.max_buffers = 7;
1049    abc_snap.is_type[0] = IS_TYPE_NONE;
1050
1051    rc = setmetainfoCommand(test_obj, &abc_snap);
1052    if (rc != MM_CAMERA_OK) {
1053       LOGE("meta info command snapshot failed\n");
1054    }
1055
1056    stream = mm_app_add_stream(test_obj, channel);
1057    if (NULL == stream) {
1058        LOGE("add stream failed\n");
1059        return NULL;
1060    }
1061
1062    stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
1063    stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
1064    stream->s_config.mem_vtbl.clean_invalidate_buf =
1065      mm_app_stream_clean_invalidate_buf;
1066    stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
1067    stream->s_config.mem_vtbl.clean_buf = mm_app_stream_clean_buf;
1068    stream->s_config.mem_vtbl.user_data = (void *)stream;
1069    stream->s_config.stream_cb = stream_cb;
1070    stream->s_config.stream_cb_sync = NULL;
1071    stream->s_config.userdata = userdata;
1072    stream->num_of_bufs = num_bufs;
1073
1074    stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
1075    memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
1076    stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_SNAPSHOT;
1077    if (num_burst == 0) {
1078        stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
1079    } else {
1080        stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_BURST;
1081        stream->s_config.stream_info->num_of_burst = num_burst;
1082    }
1083    stream->s_config.stream_info->fmt = DEFAULT_SNAPSHOT_FORMAT;
1084    if ( test_obj->buffer_width == 0 || test_obj->buffer_height == 0 ) {
1085        stream->s_config.stream_info->dim.width = DEFAULT_SNAPSHOT_WIDTH;
1086        stream->s_config.stream_info->dim.height = DEFAULT_SNAPSHOT_HEIGHT;
1087    } else {
1088        stream->s_config.stream_info->dim.width = test_obj->buffer_width;
1089        stream->s_config.stream_info->dim.height = test_obj->buffer_height;
1090    }
1091    stream->s_config.stream_info->num_bufs = num_bufs;
1092    stream->s_config.padding_info = cam_cap->padding_info;
1093    /* Make offset as zero as CPP will not be used  */
1094    stream->s_config.padding_info.offset_info.offset_x = 0;
1095    stream->s_config.padding_info.offset_info.offset_y = 0;
1096
1097    rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
1098    if (MM_CAMERA_OK != rc) {
1099        LOGE("config preview stream err=%d\n",  rc);
1100        return NULL;
1101    }
1102
1103    return stream;
1104}
1105
1106
1107mm_camera_stream_t * mm_app_add_snapshot_stream(mm_camera_test_obj_t *test_obj,
1108                                                mm_camera_channel_t *channel,
1109                                                mm_camera_buf_notify_t stream_cb,
1110                                                void *userdata,
1111                                                uint8_t num_bufs,
1112                                                uint8_t num_burst)
1113{
1114    int rc = MM_CAMERA_OK;
1115    mm_camera_stream_t *stream = NULL;
1116    cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
1117    cam_stream_size_info_t abc_snap ;
1118    memset (&abc_snap , 0, sizeof (cam_stream_size_info_t));
1119
1120    abc_snap.num_streams = 2;
1121    abc_snap.postprocess_mask[1] = 2178;
1122    abc_snap.stream_sizes[1].width  = DEFAULT_PREVIEW_WIDTH;
1123    abc_snap.stream_sizes[1].height = DEFAULT_PREVIEW_HEIGHT;
1124    abc_snap.type[1] = CAM_STREAM_TYPE_POSTVIEW;
1125
1126    abc_snap.postprocess_mask[0] = 0;
1127    if ( test_obj->buffer_width == 0 || test_obj->buffer_height == 0 ) {
1128        abc_snap.stream_sizes[0].width  = DEFAULT_SNAPSHOT_WIDTH;
1129        abc_snap.stream_sizes[0].height = DEFAULT_SNAPSHOT_HEIGHT;
1130    } else {
1131        abc_snap.stream_sizes[0].width  = test_obj->buffer_width;
1132        abc_snap.stream_sizes[0].height = test_obj->buffer_height;
1133    }
1134    abc_snap.type[0] = CAM_STREAM_TYPE_SNAPSHOT;
1135
1136    abc_snap.buffer_info.min_buffers = 7;
1137    abc_snap.buffer_info.max_buffers = 7;
1138    abc_snap.is_type[0] = IS_TYPE_NONE;
1139
1140    rc = setmetainfoCommand(test_obj, &abc_snap);
1141    if (rc != MM_CAMERA_OK) {
1142       LOGE("meta info command snapshot failed\n");
1143    }
1144
1145    stream = mm_app_add_stream(test_obj, channel);
1146    if (NULL == stream) {
1147        LOGE("add stream failed\n");
1148        return NULL;
1149    }
1150
1151    stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
1152    stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
1153    stream->s_config.mem_vtbl.clean_invalidate_buf =
1154      mm_app_stream_clean_invalidate_buf;
1155    stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
1156    stream->s_config.mem_vtbl.clean_buf = mm_app_stream_clean_buf;
1157    stream->s_config.mem_vtbl.user_data = (void *)stream;
1158    stream->s_config.stream_cb = stream_cb;
1159    stream->s_config.stream_cb_sync = NULL;
1160    stream->s_config.userdata = userdata;
1161    stream->num_of_bufs = num_bufs;
1162
1163    stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
1164    memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
1165    stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_SNAPSHOT;
1166    if (num_burst == 0) {
1167        stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
1168    } else {
1169        stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_BURST;
1170        stream->s_config.stream_info->num_of_burst = num_burst;
1171    }
1172    stream->s_config.stream_info->fmt = DEFAULT_SNAPSHOT_FORMAT;
1173    if ( test_obj->buffer_width == 0 || test_obj->buffer_height == 0 ) {
1174        stream->s_config.stream_info->dim.width = DEFAULT_SNAPSHOT_WIDTH;
1175        stream->s_config.stream_info->dim.height = DEFAULT_SNAPSHOT_HEIGHT;
1176    } else {
1177        stream->s_config.stream_info->dim.width = test_obj->buffer_width;
1178        stream->s_config.stream_info->dim.height = test_obj->buffer_height;
1179    }
1180    stream->s_config.stream_info->num_bufs = num_bufs;
1181    stream->s_config.padding_info = cam_cap->padding_info;
1182    /* Make offset as zero as CPP will not be used  */
1183    stream->s_config.padding_info.offset_info.offset_x = 0;
1184    stream->s_config.padding_info.offset_info.offset_y = 0;
1185
1186    rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
1187    if (MM_CAMERA_OK != rc) {
1188        LOGE("config preview stream err=%d\n",  rc);
1189        return NULL;
1190    }
1191
1192    return stream;
1193}
1194
1195mm_camera_channel_t * mm_app_add_preview_channel(mm_camera_test_obj_t *test_obj)
1196{
1197    mm_camera_channel_t *channel = NULL;
1198    mm_camera_stream_t *stream = NULL;
1199
1200    channel = mm_app_add_channel(test_obj,
1201                                 MM_CHANNEL_TYPE_PREVIEW,
1202                                 NULL,
1203                                 NULL,
1204                                 NULL);
1205    if (NULL == channel) {
1206        LOGE("add channel failed");
1207        return NULL;
1208    }
1209
1210    stream = mm_app_add_preview_stream(test_obj,
1211                                       channel,
1212                                       mm_app_preview_notify_cb,
1213                                       (void *)test_obj,
1214                                       PREVIEW_BUF_NUM);
1215    if (NULL == stream) {
1216        LOGE("add stream failed\n");
1217        mm_app_del_channel(test_obj, channel);
1218        return NULL;
1219    }
1220
1221    return channel;
1222}
1223
1224int mm_app_stop_and_del_channel(mm_camera_test_obj_t *test_obj,
1225                                mm_camera_channel_t *channel)
1226{
1227    int rc = MM_CAMERA_OK;
1228    mm_camera_stream_t *stream = NULL;
1229    uint8_t i;
1230    cam_stream_size_info_t abc ;
1231    memset (&abc , 0, sizeof (cam_stream_size_info_t));
1232
1233    rc = mm_app_stop_channel(test_obj, channel);
1234    if (MM_CAMERA_OK != rc) {
1235        LOGE("Stop Preview failed rc=%d\n",  rc);
1236    }
1237
1238    if (channel->num_streams <= MAX_STREAM_NUM_IN_BUNDLE) {
1239        for (i = 0; i < channel->num_streams; i++) {
1240            stream = &channel->streams[i];
1241            rc = mm_app_del_stream(test_obj, channel, stream);
1242            if (MM_CAMERA_OK != rc) {
1243                LOGE("del stream(%d) failed rc=%d\n",  i, rc);
1244            }
1245        }
1246    } else {
1247        LOGE("num_streams = %d. Should not be more than %d\n",
1248             channel->num_streams, MAX_STREAM_NUM_IN_BUNDLE);
1249    }
1250
1251    rc = setmetainfoCommand(test_obj, &abc);
1252    if (rc != MM_CAMERA_OK) {
1253       LOGE("meta info command failed\n");
1254    }
1255
1256    rc = mm_app_del_channel(test_obj, channel);
1257    if (MM_CAMERA_OK != rc) {
1258        LOGE("delete channel failed rc=%d\n",  rc);
1259    }
1260
1261    return rc;
1262}
1263
1264int mm_app_start_preview(mm_camera_test_obj_t *test_obj)
1265{
1266    int rc = MM_CAMERA_OK;
1267    mm_camera_channel_t *channel = NULL;
1268    mm_camera_stream_t *stream = NULL;
1269    mm_camera_stream_t *s_metadata = NULL;
1270    mm_camera_stream_t *s_analysis = NULL;
1271    uint8_t i;
1272
1273    channel =  mm_app_add_preview_channel(test_obj);
1274    if (NULL == channel) {
1275        LOGE("add channel failed");
1276        return -MM_CAMERA_E_GENERAL;
1277    }
1278
1279    s_metadata = mm_app_add_metadata_stream(test_obj,
1280                                            channel,
1281                                            mm_app_metadata_notify_cb,
1282                                            (void *)test_obj,
1283                                            PREVIEW_BUF_NUM);
1284    if (NULL == s_metadata) {
1285        LOGE("add metadata stream failed\n");
1286        mm_app_del_channel(test_obj, channel);
1287        return rc;
1288    }
1289
1290    s_analysis = mm_app_add_analysis_stream(test_obj,
1291                                            channel,
1292                                            NULL,
1293                                            (void *)test_obj,
1294                                            PREVIEW_BUF_NUM);
1295    if (NULL == s_analysis) {
1296        LOGE("Analysis Stream could not be added\n");
1297    }
1298
1299    rc = mm_app_start_channel(test_obj, channel);
1300    if (MM_CAMERA_OK != rc) {
1301        LOGE("start preview failed rc=%d\n",  rc);
1302        if (channel->num_streams <= MAX_STREAM_NUM_IN_BUNDLE) {
1303            for (i = 0; i < channel->num_streams; i++) {
1304                stream = &channel->streams[i];
1305                mm_app_del_stream(test_obj, channel, stream);
1306            }
1307        }
1308        mm_app_del_channel(test_obj, channel);
1309        return rc;
1310    }
1311
1312    return rc;
1313}
1314
1315int mm_app_stop_preview(mm_camera_test_obj_t *test_obj)
1316{
1317    int rc = MM_CAMERA_OK;
1318    mm_camera_channel_t *channel =
1319        mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_PREVIEW);
1320
1321    rc = mm_app_stop_and_del_channel(test_obj, channel);
1322    if (MM_CAMERA_OK != rc) {
1323        LOGE("Stop Preview failed rc=%d\n",  rc);
1324    }
1325
1326    return rc;
1327}
1328
1329int mm_app_start_preview_zsl(mm_camera_test_obj_t *test_obj)
1330{
1331    int32_t rc = MM_CAMERA_OK;
1332    mm_camera_channel_t *channel = NULL;
1333    mm_camera_stream_t *s_preview = NULL;
1334    mm_camera_stream_t *s_metadata = NULL;
1335    mm_camera_stream_t *s_main = NULL;
1336    mm_camera_channel_attr_t attr;
1337    memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
1338    attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
1339    attr.look_back = 2;
1340    attr.post_frame_skip = 0;
1341    attr.water_mark = 2;
1342    attr.max_unmatched_frames = 3;
1343    channel = mm_app_add_channel(test_obj,
1344                                 MM_CHANNEL_TYPE_ZSL,
1345                                 &attr,
1346                                 mm_app_zsl_notify_cb,
1347                                 test_obj);
1348    if (NULL == channel) {
1349        LOGE("add channel failed");
1350        return -MM_CAMERA_E_GENERAL;
1351    }
1352
1353
1354    s_main = mm_app_add_ZSL_snapshot_stream(test_obj,
1355                                        channel,
1356                                        mm_app_snapshot_notify_cb,
1357                                        (void *)test_obj,
1358                                        PREVIEW_BUF_NUM,
1359                                        0);
1360    if (NULL == s_main) {
1361        LOGE("add main snapshot stream failed\n");
1362        mm_app_del_channel(test_obj, channel);
1363        return rc;
1364    }
1365    s_preview = mm_app_add_ZSL_preview_stream(test_obj,
1366                                          channel,
1367                                          mm_app_preview_notify_cb,
1368                                          (void *)test_obj,
1369                                          PREVIEW_BUF_NUM);
1370    if (NULL == s_preview) {
1371        LOGE("add preview stream failed\n");
1372        mm_app_del_channel(test_obj, channel);
1373        return rc;
1374    }
1375
1376
1377    s_metadata = mm_app_add_metadata_stream(test_obj,
1378                                            channel,
1379                                            mm_app_metadata_notify_cb,
1380                                            (void *)test_obj,
1381                                            PREVIEW_BUF_NUM);
1382    if (NULL == s_metadata) {
1383        LOGE("add metadata stream failed\n");
1384        mm_app_del_channel(test_obj, channel);
1385        return rc;
1386    }
1387
1388    rc = mm_app_start_channel(test_obj, channel);
1389    if (MM_CAMERA_OK != rc) {
1390        LOGE("start zsl failed rc=%d\n",  rc);
1391        mm_app_del_stream(test_obj, channel, s_preview);
1392        mm_app_del_stream(test_obj, channel, s_metadata);
1393        mm_app_del_stream(test_obj, channel, s_main);
1394        mm_app_del_channel(test_obj, channel);
1395        return rc;
1396    }
1397
1398    if ( test_obj->enable_reproc ) {
1399        if ( NULL == mm_app_add_reprocess_channel(test_obj, s_main) ) {
1400            LOGE("Reprocess channel failed to initialize \n");
1401            mm_app_del_stream(test_obj, channel, s_preview);
1402#ifdef USE_METADATA_STREAM
1403            mm_app_del_stream(test_obj, channel, s_metadata);
1404#endif
1405            mm_app_del_stream(test_obj, channel, s_main);
1406            mm_app_del_channel(test_obj, channel);
1407            return rc;
1408        }
1409        rc = mm_app_start_reprocess(test_obj);
1410        if (MM_CAMERA_OK != rc) {
1411            LOGE("reprocess start failed rc=%d\n",  rc);
1412            mm_app_del_stream(test_obj, channel, s_preview);
1413#ifdef USE_METADATA_STREAM
1414            mm_app_del_stream(test_obj, channel, s_metadata);
1415#endif
1416            mm_app_del_stream(test_obj, channel, s_main);
1417            mm_app_del_channel(test_obj, channel);
1418            return rc;
1419        }
1420    }
1421
1422    return rc;
1423}
1424
1425int mm_app_stop_preview_zsl(mm_camera_test_obj_t *test_obj)
1426{
1427    int rc = MM_CAMERA_OK;
1428
1429    mm_camera_channel_t *channel =
1430        mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_ZSL);
1431
1432    rc = mm_app_stop_and_del_channel(test_obj, channel);
1433    if (MM_CAMERA_OK != rc) {
1434        LOGE("Stop Preview failed rc=%d\n",  rc);
1435    }
1436
1437    if ( test_obj->enable_reproc ) {
1438        rc |= mm_app_stop_reprocess(test_obj);
1439    }
1440
1441    return rc;
1442}
1443
1444int mm_app_initialize_fb(mm_camera_test_obj_t *test_obj)
1445{
1446    int rc = MM_CAMERA_OK;
1447    int brightness_fd;
1448    const char brightness_level[] = BACKLIGHT_LEVEL;
1449    void *fb_base = NULL;
1450
1451    assert( ( NULL != test_obj ) && ( 0 == test_obj->fb_fd ) );
1452
1453    test_obj->fb_fd = open(FB_PATH, O_RDWR);
1454    if ( 0 > test_obj->fb_fd ) {
1455        LOGE("FB device open failed rc=%d, %s\n",
1456                   -errno,
1457                   strerror(errno));
1458        rc = -errno;
1459        goto FAIL;
1460    }
1461
1462    rc = ioctl(test_obj->fb_fd, FBIOGET_VSCREENINFO, &test_obj->vinfo);
1463    if ( MM_CAMERA_OK != rc ) {
1464        LOGE("Can not retrieve screen info rc=%d, %s\n",
1465                   -errno,
1466                   strerror(errno));
1467        rc = -errno;
1468        goto FAIL;
1469    }
1470
1471    if ( ( 0 == test_obj->vinfo.yres_virtual ) ||
1472         ( 0 == test_obj->vinfo.yres ) ||
1473         ( test_obj->vinfo.yres > test_obj->vinfo.yres_virtual ) ) {
1474        LOGE("Invalid FB virtual yres: %d, yres: %d\n",
1475                   test_obj->vinfo.yres_virtual,
1476                   test_obj->vinfo.yres);
1477        rc = MM_CAMERA_E_GENERAL;
1478        goto FAIL;
1479    }
1480
1481    if ( ( 0 == test_obj->vinfo.xres_virtual ) ||
1482         ( 0 == test_obj->vinfo.xres ) ||
1483         ( test_obj->vinfo.xres > test_obj->vinfo.xres_virtual ) ) {
1484        LOGE("Invalid FB virtual xres: %d, xres: %d\n",
1485                   test_obj->vinfo.xres_virtual,
1486                   test_obj->vinfo.xres);
1487        rc = MM_CAMERA_E_GENERAL;
1488        goto FAIL;
1489    }
1490
1491    brightness_fd = open(BACKLIGHT_CONTROL, O_RDWR);
1492    if ( brightness_fd >= 0 ) {
1493        write(brightness_fd, brightness_level, strlen(brightness_level));
1494        close(brightness_fd);
1495    }
1496
1497    test_obj->slice_size = test_obj->vinfo.xres * ( test_obj->vinfo.yres - 1 ) * DEFAULT_OV_FORMAT_BPP;
1498    memset(&test_obj->data_overlay, 0, sizeof(struct mdp_overlay));
1499    test_obj->data_overlay.src.width  = test_obj->buffer_width;
1500    test_obj->data_overlay.src.height = test_obj->buffer_height;
1501    test_obj->data_overlay.src_rect.w = test_obj->buffer_width;
1502    test_obj->data_overlay.src_rect.h = test_obj->buffer_height;
1503    test_obj->data_overlay.dst_rect.w = test_obj->buffer_width;
1504    test_obj->data_overlay.dst_rect.h = test_obj->buffer_height;
1505    test_obj->data_overlay.src.format = DEFAULT_OV_FORMAT;
1506    test_obj->data_overlay.src_rect.x = 0;
1507    test_obj->data_overlay.src_rect.y = 0;
1508    test_obj->data_overlay.dst_rect.x = 0;
1509    test_obj->data_overlay.dst_rect.y = 0;
1510    test_obj->data_overlay.z_order = 2;
1511    test_obj->data_overlay.alpha = 0x80;
1512    test_obj->data_overlay.transp_mask = 0xffe0;
1513    test_obj->data_overlay.flags = MDP_FLIP_LR | MDP_FLIP_UD;
1514
1515    // Map and clear FB portion
1516    fb_base = mmap(0,
1517                   test_obj->slice_size,
1518                   PROT_WRITE,
1519                   MAP_SHARED,
1520                   test_obj->fb_fd,
1521                   0);
1522    if ( MAP_FAILED  == fb_base ) {
1523            LOGE("( Error while memory mapping frame buffer %s",
1524                       strerror(errno));
1525            rc = -errno;
1526            goto FAIL;
1527    }
1528
1529    memset(fb_base, 0, test_obj->slice_size);
1530
1531    if (ioctl(test_obj->fb_fd, FBIOPAN_DISPLAY, &test_obj->vinfo) < 0) {
1532        LOGE("FBIOPAN_DISPLAY failed!");
1533        rc = -errno;
1534        goto FAIL;
1535    }
1536
1537    munmap(fb_base, test_obj->slice_size);
1538    test_obj->data_overlay.id = (uint32_t)MSMFB_NEW_REQUEST;
1539    rc = ioctl(test_obj->fb_fd, MSMFB_OVERLAY_SET, &test_obj->data_overlay);
1540    if (rc < 0) {
1541        LOGE("MSMFB_OVERLAY_SET failed! err=%d\n",
1542               test_obj->data_overlay.id);
1543        return MM_CAMERA_E_GENERAL;
1544    }
1545    LOGE("Overlay set with overlay id: %d",  test_obj->data_overlay.id);
1546
1547    return rc;
1548
1549FAIL:
1550
1551    if ( 0 < test_obj->fb_fd ) {
1552        close(test_obj->fb_fd);
1553    }
1554
1555    return rc;
1556}
1557
1558int mm_app_close_fb(mm_camera_test_obj_t *test_obj)
1559{
1560    int rc = MM_CAMERA_OK;
1561
1562    assert( ( NULL != test_obj ) && ( 0 < test_obj->fb_fd ) );
1563
1564    if (ioctl(test_obj->fb_fd, MSMFB_OVERLAY_UNSET, &test_obj->data_overlay.id)) {
1565        LOGE("\nERROR! MSMFB_OVERLAY_UNSET failed! (Line %d)\n");
1566    }
1567
1568    if (ioctl(test_obj->fb_fd, FBIOPAN_DISPLAY, &test_obj->vinfo) < 0) {
1569        LOGE("ERROR: FBIOPAN_DISPLAY failed! line=%d\n");
1570    }
1571
1572    close(test_obj->fb_fd);
1573    test_obj->fb_fd = -1;
1574
1575    return rc;
1576}
1577
1578void memset16(void *pDst, uint16_t value, int count)
1579{
1580    uint16_t *ptr = pDst;
1581    while (count--)
1582        *ptr++ = value;
1583}
1584
1585int mm_app_overlay_display(mm_camera_test_obj_t *test_obj, int bufferFd)
1586{
1587    int rc = MM_CAMERA_OK;
1588    struct msmfb_overlay_data ovdata;
1589
1590
1591    memset(&ovdata, 0, sizeof(struct msmfb_overlay_data));
1592    ovdata.id = test_obj->data_overlay.id;
1593    ovdata.data.memory_id = bufferFd;
1594
1595    if (ioctl(test_obj->fb_fd, MSMFB_OVERLAY_PLAY, &ovdata)) {
1596        LOGE("MSMFB_OVERLAY_PLAY failed!");
1597        return MM_CAMERA_E_GENERAL;
1598    }
1599
1600    if (ioctl(test_obj->fb_fd, FBIOPAN_DISPLAY, &test_obj->vinfo) < 0) {
1601        LOGE("FBIOPAN_DISPLAY failed!");
1602        return MM_CAMERA_E_GENERAL;
1603    }
1604
1605    return rc;
1606}
1607