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