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  memcpy(pme->metadata, frame->buffer, sizeof(metadata_buffer_t));
104
105  pMetadata = (metadata_buffer_t *)frame->buffer;
106  IF_META_AVAILABLE(uint32_t, afState, CAM_INTF_META_AF_STATE, pMetadata) {
107    if ((cam_af_state_t)(*afState) == CAM_AF_STATE_FOCUSED_LOCKED ||
108            (cam_af_state_t)(*afState) == CAM_AF_STATE_NOT_FOCUSED_LOCKED) {
109        LOGE("AutoFocus Done Call Back Received\n");
110        mm_camera_app_done();
111    } else if ((cam_af_state_t)(*afState) == CAM_AF_STATE_NOT_FOCUSED_LOCKED) {
112        LOGE("AutoFocus failed\n");
113        mm_camera_app_done();
114    }
115  }
116
117  if (pme->user_metadata_cb) {
118      LOGD("[DBG] %s, user defined own metadata cb. calling it...");
119      pme->user_metadata_cb(frame);
120  }
121
122  if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
123                                          bufs->ch_id,
124                                          frame)) {
125      LOGE("Failed in Preview Qbuf\n");
126  }
127  mm_app_cache_ops((mm_camera_app_meminfo_t *)frame->mem_info,
128                   ION_IOC_INV_CACHES);
129}
130
131static void mm_app_snapshot_notify_cb(mm_camera_super_buf_t *bufs,
132                                      void *user_data)
133{
134
135    int rc = 0;
136    uint32_t i = 0;
137    mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
138    mm_camera_channel_t *channel = NULL;
139    mm_camera_stream_t *p_stream = NULL;
140    mm_camera_stream_t *m_stream = NULL;
141    mm_camera_buf_def_t *p_frame = NULL;
142    mm_camera_buf_def_t *m_frame = NULL;
143
144    /* find channel */
145    for (i = 0; i < MM_CHANNEL_TYPE_MAX; i++) {
146        if (pme->channels[i].ch_id == bufs->ch_id) {
147            channel = &pme->channels[i];
148            break;
149        }
150    }
151    if (NULL == channel) {
152        LOGE("Wrong channel id (%d)",  bufs->ch_id);
153        rc = -1;
154        goto error;
155    }
156
157    /* find snapshot stream */
158    for (i = 0; i < channel->num_streams; i++) {
159        if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_SNAPSHOT) {
160            m_stream = &channel->streams[i];
161            break;
162        }
163    }
164    if (NULL == m_stream) {
165        LOGE("cannot find snapshot stream");
166        rc = -1;
167        goto error;
168    }
169
170    /* find snapshot frame */
171    for (i = 0; i < bufs->num_bufs; i++) {
172        if (bufs->bufs[i]->stream_id == m_stream->s_id) {
173            m_frame = bufs->bufs[i];
174            break;
175        }
176    }
177    if (NULL == m_frame) {
178        LOGE("main frame is NULL");
179        rc = -1;
180        goto error;
181    }
182
183    mm_app_dump_frame(m_frame, "main", "yuv", m_frame->frame_idx);
184
185    /* find postview stream */
186    for (i = 0; i < channel->num_streams; i++) {
187        if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_POSTVIEW) {
188            p_stream = &channel->streams[i];
189            break;
190        }
191    }
192    if (NULL != p_stream) {
193        /* find preview frame */
194        for (i = 0; i < bufs->num_bufs; i++) {
195            if (bufs->bufs[i]->stream_id == p_stream->s_id) {
196                p_frame = bufs->bufs[i];
197                break;
198            }
199        }
200        if (NULL != p_frame) {
201            mm_app_dump_frame(p_frame, "postview", "yuv", p_frame->frame_idx);
202        }
203    }
204
205    mm_app_cache_ops((mm_camera_app_meminfo_t *)m_frame->mem_info,
206                     ION_IOC_CLEAN_INV_CACHES);
207
208    pme->jpeg_buf.buf.buffer = (uint8_t *)malloc(m_frame->frame_len);
209    if ( NULL == pme->jpeg_buf.buf.buffer ) {
210        LOGE("error allocating jpeg output buffer");
211        goto error;
212    }
213
214    pme->jpeg_buf.buf.frame_len = m_frame->frame_len;
215    /* create a new jpeg encoding session */
216    rc = createEncodingSession(pme, m_stream, m_frame);
217    if (0 != rc) {
218        LOGE("error creating jpeg session");
219        free(pme->jpeg_buf.buf.buffer);
220        goto error;
221    }
222
223    /* start jpeg encoding job */
224    rc = encodeData(pme, bufs, m_stream);
225    if (0 != rc) {
226        LOGE("error creating jpeg session");
227        free(pme->jpeg_buf.buf.buffer);
228        goto error;
229    }
230
231error:
232    /* buf done rcvd frames in error case */
233    if ( 0 != rc ) {
234        for (i=0; i<bufs->num_bufs; i++) {
235            if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
236                                                    bufs->ch_id,
237                                                    bufs->bufs[i])) {
238                LOGE("Failed in Qbuf\n");
239            }
240            mm_app_cache_ops((mm_camera_app_meminfo_t *)bufs->bufs[i]->mem_info,
241                             ION_IOC_INV_CACHES);
242        }
243    }
244
245    LOGD(" END\n");
246}
247
248static void mm_app_preview_notify_cb(mm_camera_super_buf_t *bufs,
249                                     void *user_data)
250{
251    uint32_t i = 0;
252    mm_camera_channel_t *channel = NULL;
253    mm_camera_stream_t *p_stream = NULL;
254    mm_camera_buf_def_t *frame = NULL;
255    mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
256
257    if (NULL == bufs || NULL == user_data) {
258        LOGE("bufs or user_data are not valid ");
259        return;
260    }
261
262    frame = bufs->bufs[0];
263
264    /* find channel */
265    for (i = 0; i < MM_CHANNEL_TYPE_MAX; i++) {
266        if (pme->channels[i].ch_id == bufs->ch_id) {
267            channel = &pme->channels[i];
268            break;
269        }
270    }
271    if (NULL == channel) {
272        LOGE("Channel object is NULL ");
273        return;
274    }
275    /* find preview stream */
276    for (i = 0; i < channel->num_streams; i++) {
277        if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_PREVIEW) {
278            p_stream = &channel->streams[i];
279            break;
280        }
281    }
282
283    if (NULL == p_stream) {
284        LOGE("cannot find preview stream");
285        return;
286    }
287
288    /* find preview frame */
289    for (i = 0; i < bufs->num_bufs; i++) {
290        if (bufs->bufs[i]->stream_id == p_stream->s_id) {
291            frame = bufs->bufs[i];
292            break;
293        }
294    }
295
296    if ( 0 < pme->fb_fd ) {
297        mm_app_overlay_display(pme, frame->fd);
298    }
299#ifdef DUMP_PRV_IN_FILE
300    {
301        char file_name[64];
302        snprintf(file_name, sizeof(file_name), "P_C%d", pme->cam->camera_handle);
303        mm_app_dump_frame(frame, file_name, "yuv", frame->frame_idx);
304    }
305#endif
306    if (pme->user_preview_cb) {
307        LOGE("[DBG] %s, user defined own preview cb. calling it...");
308        pme->user_preview_cb(frame);
309    }
310    if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
311                bufs->ch_id,
312                frame)) {
313        LOGE("Failed in Preview Qbuf\n");
314    }
315    mm_app_cache_ops((mm_camera_app_meminfo_t *)frame->mem_info,
316            ION_IOC_INV_CACHES);
317
318    LOGD(" END\n");
319}
320
321static void mm_app_zsl_notify_cb(mm_camera_super_buf_t *bufs,
322                                 void *user_data)
323{
324    int rc = MM_CAMERA_OK;
325    uint32_t i = 0;
326    mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
327    mm_camera_channel_t *channel = NULL;
328    mm_camera_stream_t *p_stream = NULL;
329    mm_camera_stream_t *m_stream = NULL;
330    mm_camera_stream_t *md_stream = NULL;
331    mm_camera_buf_def_t *p_frame = NULL;
332    mm_camera_buf_def_t *m_frame = NULL;
333    mm_camera_buf_def_t *md_frame = NULL;
334
335    LOGD(" BEGIN\n");
336
337    if (NULL == bufs || NULL == user_data) {
338        LOGE("bufs or user_data are not valid ");
339        return;
340    }
341
342    /* find channel */
343    for (i = 0; i < MM_CHANNEL_TYPE_MAX; i++) {
344        if (pme->channels[i].ch_id == bufs->ch_id) {
345            channel = &pme->channels[i];
346            break;
347        }
348    }
349    if (NULL == channel) {
350        LOGE("Wrong channel id (%d)",  bufs->ch_id);
351        return;
352    }
353
354    /* find preview stream */
355    for (i = 0; i < channel->num_streams; i++) {
356        if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_PREVIEW) {
357            p_stream = &channel->streams[i];
358            break;
359        }
360    }
361    if (NULL == p_stream) {
362        LOGE("cannot find preview stream");
363        return;
364    }
365
366    /* find snapshot stream */
367    for (i = 0; i < channel->num_streams; i++) {
368        if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_SNAPSHOT) {
369            m_stream = &channel->streams[i];
370            break;
371        }
372    }
373    if (NULL == m_stream) {
374        LOGE("cannot find snapshot stream");
375        return;
376    }
377
378    /* find metadata stream */
379    for (i = 0; i < channel->num_streams; i++) {
380        if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_METADATA) {
381            md_stream = &channel->streams[i];
382            break;
383        }
384    }
385    if (NULL == md_stream) {
386        LOGE("cannot find metadata stream");
387    }
388
389    /* find preview frame */
390    for (i = 0; i < bufs->num_bufs; i++) {
391        if (bufs->bufs[i]->stream_id == p_stream->s_id) {
392            p_frame = bufs->bufs[i];
393            break;
394        }
395    }
396
397    if(md_stream) {
398      /* find metadata frame */
399      for (i = 0; i < bufs->num_bufs; i++) {
400          if (bufs->bufs[i]->stream_id == md_stream->s_id) {
401              md_frame = bufs->bufs[i];
402              break;
403          }
404      }
405      if (!md_frame) {
406          LOGE("md_frame is null\n");
407          return;
408      }
409      if (!pme->metadata) {
410          /* App will free the metadata */
411          pme->metadata = malloc(sizeof(metadata_buffer_t));
412          if (!pme->metadata) {
413              ALOGE("not enough memory\n");
414              return;
415          }
416      }
417
418      memcpy(pme->metadata , md_frame->buffer, sizeof(metadata_buffer_t));
419    }
420    /* find snapshot frame */
421    for (i = 0; i < bufs->num_bufs; i++) {
422        if (bufs->bufs[i]->stream_id == m_stream->s_id) {
423            m_frame = bufs->bufs[i];
424            break;
425        }
426    }
427
428    if (!m_frame || !p_frame) {
429        LOGE("cannot find preview/snapshot frame");
430        return;
431    }
432
433    LOGD(" ZSL CB with fb_fd = %d, m_frame = %p, p_frame = %p \n",
434         pme->fb_fd,
435         m_frame,
436         p_frame);
437
438    if ( 0 < pme->fb_fd ) {
439        mm_app_overlay_display(pme, p_frame->fd);
440    }/* else {
441        mm_app_dump_frame(p_frame, "zsl_preview", "yuv", p_frame->frame_idx);
442        mm_app_dump_frame(m_frame, "zsl_main", "yuv", m_frame->frame_idx);
443    }*/
444
445    if ( pme->enable_reproc && ( NULL != pme->reproc_stream ) ) {
446
447        if (NULL != md_frame) {
448            rc = mm_app_do_reprocess(pme,
449                    m_frame,
450                    md_frame->buf_idx,
451                    bufs,
452                    md_stream);
453
454            if (MM_CAMERA_OK != rc ) {
455                LOGE("reprocess failed rc = %d",  rc);
456            }
457        } else {
458            LOGE("md_frame is null\n");
459        }
460
461      return;
462    }
463
464    if ( pme->encodeJpeg ) {
465        pme->jpeg_buf.buf.buffer = (uint8_t *)malloc(m_frame->frame_len);
466        if ( NULL == pme->jpeg_buf.buf.buffer ) {
467            LOGE("error allocating jpeg output buffer");
468            goto exit;
469        }
470
471        pme->jpeg_buf.buf.frame_len = m_frame->frame_len;
472        /* create a new jpeg encoding session */
473        rc = createEncodingSession(pme, m_stream, m_frame);
474        if (0 != rc) {
475            LOGE("error creating jpeg session");
476            free(pme->jpeg_buf.buf.buffer);
477            goto exit;
478        }
479
480        /* start jpeg encoding job */
481        rc = encodeData(pme, bufs, m_stream);
482        pme->encodeJpeg = 0;
483    } else {
484        if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
485                                                bufs->ch_id,
486                                                m_frame)) {
487            LOGE("Failed in main Qbuf\n");
488        }
489        mm_app_cache_ops((mm_camera_app_meminfo_t *)m_frame->mem_info,
490                         ION_IOC_INV_CACHES);
491    }
492
493exit:
494
495    if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
496                                            bufs->ch_id,
497                                            p_frame)) {
498        LOGE("Failed in preview Qbuf\n");
499    }
500    mm_app_cache_ops((mm_camera_app_meminfo_t *)p_frame->mem_info,
501                     ION_IOC_INV_CACHES);
502
503    if(md_frame) {
504      if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
505                                              bufs->ch_id,
506                                              md_frame)) {
507          LOGE("Failed in metadata Qbuf\n");
508      }
509      mm_app_cache_ops((mm_camera_app_meminfo_t *)md_frame->mem_info,
510                       ION_IOC_INV_CACHES);
511    }
512
513    LOGD(" END\n");
514}
515
516mm_camera_stream_t * mm_app_add_metadata_stream(mm_camera_test_obj_t *test_obj,
517                                               mm_camera_channel_t *channel,
518                                               mm_camera_buf_notify_t stream_cb,
519                                               void *userdata,
520                                               uint8_t num_bufs)
521{
522    int rc = MM_CAMERA_OK;
523    mm_camera_stream_t *stream = NULL;
524    cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
525    stream = mm_app_add_stream(test_obj, channel);
526    if (NULL == stream) {
527        LOGE("add stream failed\n");
528        return NULL;
529    }
530
531    stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
532    stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
533    stream->s_config.mem_vtbl.clean_invalidate_buf =
534      mm_app_stream_clean_invalidate_buf;
535    stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
536    stream->s_config.mem_vtbl.user_data = (void *)stream;
537    stream->s_config.stream_cb = stream_cb;
538    stream->s_config.stream_cb_sync = NULL;
539    stream->s_config.userdata = userdata;
540    stream->num_of_bufs = num_bufs;
541
542    stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
543    memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
544    stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_METADATA;
545    stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
546    stream->s_config.stream_info->fmt = DEFAULT_PREVIEW_FORMAT;
547    stream->s_config.stream_info->dim.width = sizeof(metadata_buffer_t);
548    stream->s_config.stream_info->dim.height = 1;
549    stream->s_config.padding_info = cam_cap->padding_info;
550
551    rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
552    if (MM_CAMERA_OK != rc) {
553        LOGE("config preview stream err=%d\n",  rc);
554        return NULL;
555    }
556
557    return stream;
558}
559
560cam_dimension_t mm_app_get_analysis_stream_dim(
561                                               const mm_camera_test_obj_t *test_obj,
562                                               const cam_dimension_t* preview_dim)
563{
564    cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
565    cam_dimension_t max_analysis_dim = cam_cap->analysis_max_res;
566    cam_dimension_t analysis_dim = {0, 0};
567
568    if (preview_dim->width > max_analysis_dim.width ||
569            preview_dim->height > max_analysis_dim.height) {
570        double max_ratio, requested_ratio;
571
572        max_ratio = (double)max_analysis_dim.width / (double)max_analysis_dim.height;
573        requested_ratio = (double)preview_dim->width / (double)preview_dim->height;
574
575        if (max_ratio < requested_ratio) {
576            analysis_dim.width = analysis_dim.width;
577            analysis_dim.height = (int32_t)((double)analysis_dim.width / requested_ratio);
578        } else {
579            analysis_dim.height = analysis_dim.height;
580            analysis_dim.width = (int32_t)((double)analysis_dim.height * requested_ratio);
581        }
582        analysis_dim.width &= ~0x1;
583        analysis_dim.height &= ~0x1;
584    } else {
585        analysis_dim = *preview_dim;
586    }
587
588    LOGI("analysis stream dim (%d x %d)\n",  analysis_dim.width, analysis_dim.height);
589    return analysis_dim;
590}
591
592mm_camera_stream_t * mm_app_add_analysis_stream(mm_camera_test_obj_t *test_obj,
593                                               mm_camera_channel_t *channel,
594                                               mm_camera_buf_notify_t stream_cb,
595                                               void *userdata,
596                                               uint8_t num_bufs)
597{
598    int rc = MM_CAMERA_OK;
599    mm_camera_stream_t *stream = NULL;
600    cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
601    cam_dimension_t preview_dim = {0, 0};
602    cam_dimension_t analysis_dim = {0, 0};
603
604
605    stream = mm_app_add_stream(test_obj, channel);
606    if (NULL == stream) {
607        LOGE("add stream failed\n");
608        return NULL;
609    }
610
611    if ((test_obj->preview_resolution.user_input_display_width == 0) ||
612           ( test_obj->preview_resolution.user_input_display_height == 0)) {
613        preview_dim.width = DEFAULT_PREVIEW_WIDTH;
614        preview_dim.height = DEFAULT_PREVIEW_HEIGHT;
615    } else {
616        preview_dim.width = test_obj->preview_resolution.user_input_display_width;
617        preview_dim.height = test_obj->preview_resolution.user_input_display_height;
618    }
619
620    analysis_dim = mm_app_get_analysis_stream_dim(test_obj, &preview_dim);
621    LOGI("analysis stream dimesion: %d x %d\n",
622            analysis_dim.width, analysis_dim.height);
623
624    stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
625    stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
626    stream->s_config.mem_vtbl.clean_invalidate_buf =
627      mm_app_stream_clean_invalidate_buf;
628    stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
629    stream->s_config.mem_vtbl.user_data = (void *)stream;
630    stream->s_config.stream_cb = stream_cb;
631    stream->s_config.userdata = userdata;
632    stream->num_of_bufs = num_bufs;
633
634    stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
635    memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
636    stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_ANALYSIS;
637    stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
638    stream->s_config.stream_info->fmt = DEFAULT_PREVIEW_FORMAT;
639    stream->s_config.stream_info->dim = analysis_dim;
640    stream->s_config.padding_info = cam_cap->analysis_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
651mm_camera_stream_t * mm_app_add_preview_stream(mm_camera_test_obj_t *test_obj,
652                                               mm_camera_channel_t *channel,
653                                               mm_camera_buf_notify_t stream_cb,
654                                               void *userdata,
655                                               uint8_t num_bufs)
656{
657    int rc = MM_CAMERA_OK;
658    mm_camera_stream_t *stream = NULL;
659    cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
660    cam_dimension_t preview_dim = {0, 0};
661    cam_dimension_t analysis_dim = {0, 0};
662
663    if ((test_obj->preview_resolution.user_input_display_width == 0) ||
664           ( test_obj->preview_resolution.user_input_display_height == 0)) {
665        preview_dim.width = DEFAULT_PREVIEW_WIDTH;
666        preview_dim.height = DEFAULT_PREVIEW_HEIGHT;
667    } else {
668        preview_dim.width = test_obj->preview_resolution.user_input_display_width;
669        preview_dim.height = test_obj->preview_resolution.user_input_display_height;
670    }
671    LOGI("preview dimesion: %d x %d\n",  preview_dim.width, preview_dim.height);
672
673    analysis_dim = mm_app_get_analysis_stream_dim(test_obj, &preview_dim);
674    LOGI("analysis stream dimesion: %d x %d\n",
675            analysis_dim.width, analysis_dim.height);
676
677    uint32_t analysis_pp_mask = cam_cap->qcom_supported_feature_mask &
678                                        (CAM_QCOM_FEATURE_SHARPNESS |
679                                         CAM_QCOM_FEATURE_EFFECT |
680                                         CAM_QCOM_FEATURE_DENOISE2D);
681    LOGI("analysis stream pp mask:%x\n",  analysis_pp_mask);
682
683    cam_stream_size_info_t abc ;
684    memset (&abc , 0, sizeof (cam_stream_size_info_t));
685
686    abc.num_streams = 2;
687    abc.postprocess_mask[0] = 2178;
688    abc.stream_sizes[0].width = preview_dim.width;
689    abc.stream_sizes[0].height = preview_dim.height;
690    abc.type[0] = CAM_STREAM_TYPE_PREVIEW;
691
692    abc.postprocess_mask[1] = analysis_pp_mask;
693    abc.stream_sizes[1].width = analysis_dim.width;
694    abc.stream_sizes[1].height = analysis_dim.height;
695    abc.type[1] = CAM_STREAM_TYPE_ANALYSIS;
696
697    abc.buffer_info.min_buffers = 10;
698    abc.buffer_info.max_buffers = 10;
699    abc.is_type = IS_TYPE_NONE;
700
701    rc = setmetainfoCommand(test_obj, &abc);
702    if (rc != MM_CAMERA_OK) {
703       LOGE("meta info command failed\n");
704    }
705
706    stream = mm_app_add_stream(test_obj, channel);
707    if (NULL == stream) {
708        LOGE("add stream failed\n");
709        return NULL;
710    }
711    stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
712    stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
713    stream->s_config.mem_vtbl.clean_invalidate_buf =
714      mm_app_stream_clean_invalidate_buf;
715    stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
716    stream->s_config.mem_vtbl.user_data = (void *)stream;
717    stream->s_config.stream_cb = stream_cb;
718    stream->s_config.stream_cb_sync = NULL;
719    stream->s_config.userdata = userdata;
720    stream->num_of_bufs = num_bufs;
721
722    stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
723    memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
724    stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_PREVIEW;
725    stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
726    stream->s_config.stream_info->fmt = DEFAULT_PREVIEW_FORMAT;
727
728    stream->s_config.stream_info->dim.width = preview_dim.width;
729    stream->s_config.stream_info->dim.height = preview_dim.height;
730
731    stream->s_config.padding_info = cam_cap->padding_info;
732
733    rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
734    if (MM_CAMERA_OK != rc) {
735        LOGE("config preview stream err=%d\n",  rc);
736        return NULL;
737    }
738
739    return stream;
740}
741
742mm_camera_stream_t * mm_app_add_raw_stream(mm_camera_test_obj_t *test_obj,
743                                                mm_camera_channel_t *channel,
744                                                mm_camera_buf_notify_t stream_cb,
745                                                void *userdata,
746                                                uint8_t num_bufs,
747                                                uint8_t num_burst)
748{
749    int rc = MM_CAMERA_OK;
750    mm_camera_stream_t *stream = NULL;
751    cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
752
753    cam_stream_size_info_t abc ;
754    memset (&abc , 0, sizeof (cam_stream_size_info_t));
755
756    abc.num_streams = 1;
757    abc.postprocess_mask[0] = 0;
758
759    if ( test_obj->buffer_width == 0 || test_obj->buffer_height == 0 ) {
760        abc.stream_sizes[0].width = DEFAULT_SNAPSHOT_WIDTH;
761        abc.stream_sizes[0].height = DEFAULT_SNAPSHOT_HEIGHT;
762    } else {
763        abc.stream_sizes[0].width = (int32_t)test_obj->buffer_width;
764        abc.stream_sizes[0].height = (int32_t)test_obj->buffer_height;
765    }
766    abc.type[0] = CAM_STREAM_TYPE_RAW;
767
768    abc.buffer_info.min_buffers = num_bufs;
769    abc.buffer_info.max_buffers = num_bufs;
770    abc.is_type = IS_TYPE_NONE;
771
772    rc = setmetainfoCommand(test_obj, &abc);
773    if (rc != MM_CAMERA_OK) {
774       LOGE("meta info command failed\n");
775    }
776
777    stream = mm_app_add_stream(test_obj, channel);
778    if (NULL == stream) {
779        LOGE("add stream failed\n");
780        return NULL;
781    }
782
783    stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
784    stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
785    stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
786    stream->s_config.mem_vtbl.user_data = (void *)stream;
787    stream->s_config.stream_cb = stream_cb;
788    stream->s_config.stream_cb_sync = NULL;
789    stream->s_config.userdata = userdata;
790    stream->num_of_bufs = num_bufs;
791
792    stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
793    memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
794    stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_RAW;
795    if (num_burst == 0) {
796        stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
797    } else {
798        stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_BURST;
799        stream->s_config.stream_info->num_of_burst = num_burst;
800    }
801    stream->s_config.stream_info->fmt = test_obj->buffer_format;
802    if ( test_obj->buffer_width == 0 || test_obj->buffer_height == 0 ) {
803        stream->s_config.stream_info->dim.width = DEFAULT_SNAPSHOT_WIDTH;
804        stream->s_config.stream_info->dim.height = DEFAULT_SNAPSHOT_HEIGHT;
805    } else {
806        stream->s_config.stream_info->dim.width = (int32_t)test_obj->buffer_width;
807        stream->s_config.stream_info->dim.height = (int32_t)test_obj->buffer_height;
808    }
809    stream->s_config.padding_info = cam_cap->padding_info;
810
811    rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
812    if (MM_CAMERA_OK != rc) {
813        LOGE("config preview stream err=%d\n",  rc);
814        return NULL;
815    }
816
817    return stream;
818}
819
820mm_camera_stream_t * mm_app_add_snapshot_stream(mm_camera_test_obj_t *test_obj,
821                                                mm_camera_channel_t *channel,
822                                                mm_camera_buf_notify_t stream_cb,
823                                                void *userdata,
824                                                uint8_t num_bufs,
825                                                uint8_t num_burst)
826{
827    int rc = MM_CAMERA_OK;
828    mm_camera_stream_t *stream = NULL;
829    cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
830    cam_stream_size_info_t abc_snap ;
831    memset (&abc_snap , 0, sizeof (cam_stream_size_info_t));
832
833    abc_snap.num_streams = 2;
834    abc_snap.postprocess_mask[1] = 2178;
835    abc_snap.stream_sizes[1].width = DEFAULT_PREVIEW_WIDTH;
836    abc_snap.stream_sizes[1].height = DEFAULT_PREVIEW_HEIGHT;
837    abc_snap.type[1] = CAM_STREAM_TYPE_POSTVIEW;
838
839    abc_snap.postprocess_mask[0] = 0;
840    abc_snap.stream_sizes[0].width = DEFAULT_SNAPSHOT_WIDTH;
841    abc_snap.stream_sizes[0].height = DEFAULT_SNAPSHOT_HEIGHT;
842    abc_snap.type[0] = CAM_STREAM_TYPE_SNAPSHOT;
843
844    abc_snap.buffer_info.min_buffers = 7;
845    abc_snap.buffer_info.max_buffers = 7;
846    abc_snap.is_type = IS_TYPE_NONE;
847
848    rc = setmetainfoCommand(test_obj, &abc_snap);
849    if (rc != MM_CAMERA_OK) {
850       LOGE("meta info command snapshot failed\n");
851    }
852
853    stream = mm_app_add_stream(test_obj, channel);
854    if (NULL == stream) {
855        LOGE("add stream failed\n");
856        return NULL;
857    }
858
859    stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
860    stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
861    stream->s_config.mem_vtbl.clean_invalidate_buf =
862      mm_app_stream_clean_invalidate_buf;
863    stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
864    stream->s_config.mem_vtbl.user_data = (void *)stream;
865    stream->s_config.stream_cb = stream_cb;
866    stream->s_config.stream_cb_sync = NULL;
867    stream->s_config.userdata = userdata;
868    stream->num_of_bufs = num_bufs;
869
870    stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
871    memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
872    stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_SNAPSHOT;
873    if (num_burst == 0) {
874        stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
875    } else {
876        stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_BURST;
877        stream->s_config.stream_info->num_of_burst = num_burst;
878    }
879    stream->s_config.stream_info->fmt = DEFAULT_SNAPSHOT_FORMAT;
880    if ( test_obj->buffer_width == 0 || test_obj->buffer_height == 0 ) {
881        stream->s_config.stream_info->dim.width = DEFAULT_SNAPSHOT_WIDTH;
882        stream->s_config.stream_info->dim.height = DEFAULT_SNAPSHOT_HEIGHT;
883    } else {
884        stream->s_config.stream_info->dim.width = DEFAULT_SNAPSHOT_WIDTH;
885        stream->s_config.stream_info->dim.height = DEFAULT_SNAPSHOT_HEIGHT;
886    }
887    stream->s_config.padding_info = cam_cap->padding_info;
888
889    rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
890    if (MM_CAMERA_OK != rc) {
891        LOGE("config preview stream err=%d\n",  rc);
892        return NULL;
893    }
894
895    return stream;
896}
897
898mm_camera_channel_t * mm_app_add_preview_channel(mm_camera_test_obj_t *test_obj)
899{
900    mm_camera_channel_t *channel = NULL;
901    mm_camera_stream_t *stream = NULL;
902
903    channel = mm_app_add_channel(test_obj,
904                                 MM_CHANNEL_TYPE_PREVIEW,
905                                 NULL,
906                                 NULL,
907                                 NULL);
908    if (NULL == channel) {
909        LOGE("add channel failed");
910        return NULL;
911    }
912
913    stream = mm_app_add_preview_stream(test_obj,
914                                       channel,
915                                       mm_app_preview_notify_cb,
916                                       (void *)test_obj,
917                                       PREVIEW_BUF_NUM);
918    if (NULL == stream) {
919        LOGE("add stream failed\n");
920        mm_app_del_channel(test_obj, channel);
921        return NULL;
922    }
923
924    return channel;
925}
926
927int mm_app_stop_and_del_channel(mm_camera_test_obj_t *test_obj,
928                                mm_camera_channel_t *channel)
929{
930    int rc = MM_CAMERA_OK;
931    mm_camera_stream_t *stream = NULL;
932    uint8_t i;
933    cam_stream_size_info_t abc ;
934    memset (&abc , 0, sizeof (cam_stream_size_info_t));
935
936    rc = mm_app_stop_channel(test_obj, channel);
937    if (MM_CAMERA_OK != rc) {
938        LOGE("Stop Preview failed rc=%d\n",  rc);
939    }
940
941    if (channel->num_streams <= MAX_STREAM_NUM_IN_BUNDLE) {
942        for (i = 0; i < channel->num_streams; i++) {
943            stream = &channel->streams[i];
944            rc = mm_app_del_stream(test_obj, channel, stream);
945            if (MM_CAMERA_OK != rc) {
946                LOGE("del stream(%d) failed rc=%d\n",  i, rc);
947            }
948        }
949    } else {
950        LOGE("num_streams = %d. Should not be more than %d\n",
951             channel->num_streams, MAX_STREAM_NUM_IN_BUNDLE);
952    }
953
954    rc = setmetainfoCommand(test_obj, &abc);
955    if (rc != MM_CAMERA_OK) {
956       LOGE("meta info command failed\n");
957    }
958
959    rc = mm_app_del_channel(test_obj, channel);
960    if (MM_CAMERA_OK != rc) {
961        LOGE("delete channel failed rc=%d\n",  rc);
962    }
963
964    return rc;
965}
966
967int mm_app_start_preview(mm_camera_test_obj_t *test_obj)
968{
969    int rc = MM_CAMERA_OK;
970    mm_camera_channel_t *channel = NULL;
971    mm_camera_stream_t *stream = NULL;
972    mm_camera_stream_t *s_metadata = NULL;
973    mm_camera_stream_t *s_analysis = NULL;
974    uint8_t i;
975
976    channel =  mm_app_add_preview_channel(test_obj);
977    if (NULL == channel) {
978        LOGE("add channel failed");
979        return -MM_CAMERA_E_GENERAL;
980    }
981
982    s_metadata = mm_app_add_metadata_stream(test_obj,
983                                            channel,
984                                            mm_app_metadata_notify_cb,
985                                            (void *)test_obj,
986                                            PREVIEW_BUF_NUM);
987    if (NULL == s_metadata) {
988        LOGE("add metadata stream failed\n");
989        mm_app_del_channel(test_obj, channel);
990        return rc;
991    }
992
993    s_analysis = mm_app_add_analysis_stream(test_obj,
994                                            channel,
995                                            NULL,
996                                            (void *)test_obj,
997                                            PREVIEW_BUF_NUM);
998    if (NULL == s_analysis) {
999        LOGE("add metadata stream failed\n");
1000        mm_app_del_channel(test_obj, channel);
1001        return rc;
1002    }
1003
1004    rc = mm_app_start_channel(test_obj, channel);
1005    if (MM_CAMERA_OK != rc) {
1006        LOGE("start preview failed rc=%d\n",  rc);
1007        if (channel->num_streams <= MAX_STREAM_NUM_IN_BUNDLE) {
1008            for (i = 0; i < channel->num_streams; i++) {
1009                stream = &channel->streams[i];
1010                mm_app_del_stream(test_obj, channel, stream);
1011            }
1012        }
1013        mm_app_del_channel(test_obj, channel);
1014        return rc;
1015    }
1016
1017    return rc;
1018}
1019
1020int mm_app_stop_preview(mm_camera_test_obj_t *test_obj)
1021{
1022    int rc = MM_CAMERA_OK;
1023    mm_camera_channel_t *channel =
1024        mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_PREVIEW);
1025
1026    rc = mm_app_stop_and_del_channel(test_obj, channel);
1027    if (MM_CAMERA_OK != rc) {
1028        LOGE("Stop Preview failed rc=%d\n",  rc);
1029    }
1030
1031    return rc;
1032}
1033
1034int mm_app_start_preview_zsl(mm_camera_test_obj_t *test_obj)
1035{
1036    int32_t rc = MM_CAMERA_OK;
1037    mm_camera_channel_t *channel = NULL;
1038    mm_camera_stream_t *s_preview = NULL;
1039    mm_camera_stream_t *s_metadata = NULL;
1040    mm_camera_stream_t *s_main = NULL;
1041    mm_camera_channel_attr_t attr;
1042    memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
1043    attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
1044    attr.look_back = 2;
1045    attr.post_frame_skip = 0;
1046    attr.water_mark = 2;
1047    attr.max_unmatched_frames = 3;
1048    channel = mm_app_add_channel(test_obj,
1049                                 MM_CHANNEL_TYPE_ZSL,
1050                                 &attr,
1051                                 mm_app_zsl_notify_cb,
1052                                 test_obj);
1053    if (NULL == channel) {
1054        LOGE("add channel failed");
1055        return -MM_CAMERA_E_GENERAL;
1056    }
1057
1058    s_preview = mm_app_add_preview_stream(test_obj,
1059                                          channel,
1060                                          mm_app_preview_notify_cb,
1061                                          (void *)test_obj,
1062                                          PREVIEW_BUF_NUM);
1063    if (NULL == s_preview) {
1064        LOGE("add preview stream failed\n");
1065        mm_app_del_channel(test_obj, channel);
1066        return rc;
1067    }
1068
1069    s_main = mm_app_add_snapshot_stream(test_obj,
1070                                        channel,
1071                                        mm_app_snapshot_notify_cb,
1072                                        (void *)test_obj,
1073                                        PREVIEW_BUF_NUM,
1074                                        0);
1075    if (NULL == s_main) {
1076        LOGE("add main snapshot stream failed\n");
1077        mm_app_del_stream(test_obj, channel, s_preview);
1078        mm_app_del_channel(test_obj, channel);
1079        return rc;
1080    }
1081
1082    s_metadata = mm_app_add_metadata_stream(test_obj,
1083                                            channel,
1084                                            mm_app_metadata_notify_cb,
1085                                            (void *)test_obj,
1086                                            PREVIEW_BUF_NUM);
1087    if (NULL == s_metadata) {
1088        LOGE("add metadata stream failed\n");
1089        mm_app_del_channel(test_obj, channel);
1090        return rc;
1091    }
1092
1093    rc = mm_app_start_channel(test_obj, channel);
1094    if (MM_CAMERA_OK != rc) {
1095        LOGE("start zsl failed rc=%d\n",  rc);
1096        mm_app_del_stream(test_obj, channel, s_preview);
1097        mm_app_del_stream(test_obj, channel, s_metadata);
1098        mm_app_del_stream(test_obj, channel, s_main);
1099        mm_app_del_channel(test_obj, channel);
1100        return rc;
1101    }
1102
1103    if ( test_obj->enable_reproc ) {
1104        if ( NULL == mm_app_add_reprocess_channel(test_obj, s_main) ) {
1105            LOGE("Reprocess channel failed to initialize \n");
1106            mm_app_del_stream(test_obj, channel, s_preview);
1107#ifdef USE_METADATA_STREAM
1108            mm_app_del_stream(test_obj, channel, s_metadata);
1109#endif
1110            mm_app_del_stream(test_obj, channel, s_main);
1111            mm_app_del_channel(test_obj, channel);
1112            return rc;
1113        }
1114        rc = mm_app_start_reprocess(test_obj);
1115        if (MM_CAMERA_OK != rc) {
1116            LOGE("reprocess start failed rc=%d\n",  rc);
1117            mm_app_del_stream(test_obj, channel, s_preview);
1118#ifdef USE_METADATA_STREAM
1119            mm_app_del_stream(test_obj, channel, s_metadata);
1120#endif
1121            mm_app_del_stream(test_obj, channel, s_main);
1122            mm_app_del_channel(test_obj, channel);
1123            return rc;
1124        }
1125    }
1126
1127    return rc;
1128}
1129
1130int mm_app_stop_preview_zsl(mm_camera_test_obj_t *test_obj)
1131{
1132    int rc = MM_CAMERA_OK;
1133
1134    mm_camera_channel_t *channel =
1135        mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_ZSL);
1136
1137    rc = mm_app_stop_and_del_channel(test_obj, channel);
1138    if (MM_CAMERA_OK != rc) {
1139        LOGE("Stop Preview failed rc=%d\n",  rc);
1140    }
1141
1142    if ( test_obj->enable_reproc ) {
1143        rc |= mm_app_stop_reprocess(test_obj);
1144    }
1145
1146    return rc;
1147}
1148
1149int mm_app_initialize_fb(mm_camera_test_obj_t *test_obj)
1150{
1151    int rc = MM_CAMERA_OK;
1152    int brightness_fd;
1153    const char brightness_level[] = BACKLIGHT_LEVEL;
1154    void *fb_base = NULL;
1155
1156    assert( ( NULL != test_obj ) && ( 0 == test_obj->fb_fd ) );
1157
1158    test_obj->fb_fd = open(FB_PATH, O_RDWR);
1159    if ( 0 > test_obj->fb_fd ) {
1160        LOGE("FB device open failed rc=%d, %s\n",
1161                   -errno,
1162                   strerror(errno));
1163        rc = -errno;
1164        goto FAIL;
1165    }
1166
1167    rc = ioctl(test_obj->fb_fd, FBIOGET_VSCREENINFO, &test_obj->vinfo);
1168    if ( MM_CAMERA_OK != rc ) {
1169        LOGE("Can not retrieve screen info rc=%d, %s\n",
1170                   -errno,
1171                   strerror(errno));
1172        rc = -errno;
1173        goto FAIL;
1174    }
1175
1176    if ( ( 0 == test_obj->vinfo.yres_virtual ) ||
1177         ( 0 == test_obj->vinfo.yres ) ||
1178         ( test_obj->vinfo.yres > test_obj->vinfo.yres_virtual ) ) {
1179        LOGE("Invalid FB virtual yres: %d, yres: %d\n",
1180                   test_obj->vinfo.yres_virtual,
1181                   test_obj->vinfo.yres);
1182        rc = MM_CAMERA_E_GENERAL;
1183        goto FAIL;
1184    }
1185
1186    if ( ( 0 == test_obj->vinfo.xres_virtual ) ||
1187         ( 0 == test_obj->vinfo.xres ) ||
1188         ( test_obj->vinfo.xres > test_obj->vinfo.xres_virtual ) ) {
1189        LOGE("Invalid FB virtual xres: %d, xres: %d\n",
1190                   test_obj->vinfo.xres_virtual,
1191                   test_obj->vinfo.xres);
1192        rc = MM_CAMERA_E_GENERAL;
1193        goto FAIL;
1194    }
1195
1196    brightness_fd = open(BACKLIGHT_CONTROL, O_RDWR);
1197    if ( brightness_fd >= 0 ) {
1198        write(brightness_fd, brightness_level, strlen(brightness_level));
1199        close(brightness_fd);
1200    }
1201
1202    test_obj->slice_size = test_obj->vinfo.xres * ( test_obj->vinfo.yres - 1 ) * DEFAULT_OV_FORMAT_BPP;
1203    memset(&test_obj->data_overlay, 0, sizeof(struct mdp_overlay));
1204    test_obj->data_overlay.src.width  = test_obj->buffer_width;
1205    test_obj->data_overlay.src.height = test_obj->buffer_height;
1206    test_obj->data_overlay.src_rect.w = test_obj->buffer_width;
1207    test_obj->data_overlay.src_rect.h = test_obj->buffer_height;
1208    test_obj->data_overlay.dst_rect.w = test_obj->buffer_width;
1209    test_obj->data_overlay.dst_rect.h = test_obj->buffer_height;
1210    test_obj->data_overlay.src.format = DEFAULT_OV_FORMAT;
1211    test_obj->data_overlay.src_rect.x = 0;
1212    test_obj->data_overlay.src_rect.y = 0;
1213    test_obj->data_overlay.dst_rect.x = 0;
1214    test_obj->data_overlay.dst_rect.y = 0;
1215    test_obj->data_overlay.z_order = 2;
1216    test_obj->data_overlay.alpha = 0x80;
1217    test_obj->data_overlay.transp_mask = 0xffe0;
1218    test_obj->data_overlay.flags = MDP_FLIP_LR | MDP_FLIP_UD;
1219
1220    // Map and clear FB portion
1221    fb_base = mmap(0,
1222                   test_obj->slice_size,
1223                   PROT_WRITE,
1224                   MAP_SHARED,
1225                   test_obj->fb_fd,
1226                   0);
1227    if ( MAP_FAILED  == fb_base ) {
1228            LOGE("( Error while memory mapping frame buffer %s",
1229                       strerror(errno));
1230            rc = -errno;
1231            goto FAIL;
1232    }
1233
1234    memset(fb_base, 0, test_obj->slice_size);
1235
1236    if (ioctl(test_obj->fb_fd, FBIOPAN_DISPLAY, &test_obj->vinfo) < 0) {
1237        LOGE("FBIOPAN_DISPLAY failed!");
1238        rc = -errno;
1239        goto FAIL;
1240    }
1241
1242    munmap(fb_base, test_obj->slice_size);
1243    test_obj->data_overlay.id = (uint32_t)MSMFB_NEW_REQUEST;
1244    rc = ioctl(test_obj->fb_fd, MSMFB_OVERLAY_SET, &test_obj->data_overlay);
1245    if (rc < 0) {
1246        LOGE("MSMFB_OVERLAY_SET failed! err=%d\n",
1247               test_obj->data_overlay.id);
1248        return MM_CAMERA_E_GENERAL;
1249    }
1250    LOGE("Overlay set with overlay id: %d",  test_obj->data_overlay.id);
1251
1252    return rc;
1253
1254FAIL:
1255
1256    if ( 0 < test_obj->fb_fd ) {
1257        close(test_obj->fb_fd);
1258    }
1259
1260    return rc;
1261}
1262
1263int mm_app_close_fb(mm_camera_test_obj_t *test_obj)
1264{
1265    int rc = MM_CAMERA_OK;
1266
1267    assert( ( NULL != test_obj ) && ( 0 < test_obj->fb_fd ) );
1268
1269    if (ioctl(test_obj->fb_fd, MSMFB_OVERLAY_UNSET, &test_obj->data_overlay.id)) {
1270        LOGE("\nERROR! MSMFB_OVERLAY_UNSET failed! (Line %d)\n");
1271    }
1272
1273    if (ioctl(test_obj->fb_fd, FBIOPAN_DISPLAY, &test_obj->vinfo) < 0) {
1274        LOGE("ERROR: FBIOPAN_DISPLAY failed! line=%d\n");
1275    }
1276
1277    close(test_obj->fb_fd);
1278    test_obj->fb_fd = -1;
1279
1280    return rc;
1281}
1282
1283void memset16(void *pDst, uint16_t value, int count)
1284{
1285    uint16_t *ptr = pDst;
1286    while (count--)
1287        *ptr++ = value;
1288}
1289
1290int mm_app_overlay_display(mm_camera_test_obj_t *test_obj, int bufferFd)
1291{
1292    int rc = MM_CAMERA_OK;
1293    struct msmfb_overlay_data ovdata;
1294
1295
1296    memset(&ovdata, 0, sizeof(struct msmfb_overlay_data));
1297    ovdata.id = test_obj->data_overlay.id;
1298    ovdata.data.memory_id = bufferFd;
1299
1300    if (ioctl(test_obj->fb_fd, MSMFB_OVERLAY_PLAY, &ovdata)) {
1301        LOGE("MSMFB_OVERLAY_PLAY failed!");
1302        return MM_CAMERA_E_GENERAL;
1303    }
1304
1305    if (ioctl(test_obj->fb_fd, FBIOPAN_DISPLAY, &test_obj->vinfo) < 0) {
1306        LOGE("FBIOPAN_DISPLAY failed!");
1307        return MM_CAMERA_E_GENERAL;
1308    }
1309
1310    return rc;
1311}
1312