1 /*
2 Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are
6 met:
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
17 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #include "mm_qcamera_dbg.h"
31 #include "mm_qcamera_app.h"
32 #include <assert.h>
33 #include <sys/mman.h>
34 #include <semaphore.h>
35
mm_app_metadata_notify_cb(mm_camera_super_buf_t * bufs,void * user_data)36 static void mm_app_metadata_notify_cb(mm_camera_super_buf_t *bufs,
37 void *user_data)
38 {
39 uint32_t i = 0;
40 mm_camera_channel_t *channel = NULL;
41 mm_camera_stream_t *p_stream = NULL;
42 mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
43 mm_camera_buf_def_t *frame;
44 metadata_buffer_t *pMetadata;
45
46 if (NULL == bufs || NULL == user_data) {
47 CDBG_ERROR("%s: bufs or user_data are not valid ", __func__);
48 return;
49 }
50 frame = bufs->bufs[0];
51
52 /* find channel */
53 for (i = 0; i < MM_CHANNEL_TYPE_MAX; i++) {
54 if (pme->channels[i].ch_id == bufs->ch_id) {
55 channel = &pme->channels[i];
56 break;
57 }
58 }
59
60 if (NULL == channel) {
61 CDBG_ERROR("%s: Channel object is NULL ", __func__);
62 return;
63 }
64
65 /* find preview stream */
66 for (i = 0; i < channel->num_streams; i++) {
67 if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_METADATA) {
68 p_stream = &channel->streams[i];
69 break;
70 }
71 }
72
73 if (NULL == p_stream) {
74 CDBG_ERROR("%s: cannot find metadata stream", __func__);
75 return;
76 }
77
78 /* find preview frame */
79 for (i = 0; i < bufs->num_bufs; i++) {
80 if (bufs->bufs[i]->stream_id == p_stream->s_id) {
81 frame = bufs->bufs[i];
82 break;
83 }
84 }
85
86 if (pme->metadata == NULL) {
87 /* The app will free the meta data, we don't need to bother here */
88 pme->metadata = malloc(sizeof(metadata_buffer_t));
89 if (NULL == pme->metadata) {
90 CDBG_ERROR("%s: Canot allocate metadata memory\n", __func__);
91 return;
92 }
93 }
94 memcpy(pme->metadata, frame->buffer, sizeof(metadata_buffer_t));
95
96 pMetadata = (metadata_buffer_t *)frame->buffer;
97 IF_META_AVAILABLE(cam_auto_focus_data_t, focus_data, CAM_INTF_META_AUTOFOCUS_DATA,
98 pMetadata) {
99 if (focus_data->focus_state == CAM_AF_FOCUSED ||
100 focus_data->focus_state == CAM_AF_NOT_FOCUSED) {
101 CDBG_ERROR("%s: AutoFocus Done Call Back Received\n",__func__);
102 mm_camera_app_done();
103 } else if (focus_data->focus_state == CAM_AF_NOT_FOCUSED) {
104 CDBG_ERROR("%s: AutoFocus failed\n",__func__);
105 mm_camera_app_done();
106 }
107 }
108
109 if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
110 bufs->ch_id,
111 frame)) {
112 CDBG_ERROR("%s: Failed in Preview Qbuf\n", __func__);
113 }
114 mm_app_cache_ops((mm_camera_app_meminfo_t *)frame->mem_info,
115 ION_IOC_INV_CACHES);
116 }
117
mm_app_preview_notify_cb(mm_camera_super_buf_t * bufs,void * user_data)118 static void mm_app_preview_notify_cb(mm_camera_super_buf_t *bufs,
119 void *user_data)
120 {
121 uint32_t i = 0;
122 mm_camera_channel_t *channel = NULL;
123 mm_camera_stream_t *p_stream = NULL;
124 mm_camera_buf_def_t *frame = NULL;
125 mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
126
127 if (NULL == bufs || NULL == user_data) {
128 CDBG_ERROR("%s: bufs or user_data are not valid ", __func__);
129 return;
130 }
131
132 frame = bufs->bufs[0];
133
134 /* find channel */
135 for (i = 0; i < MM_CHANNEL_TYPE_MAX; i++) {
136 if (pme->channels[i].ch_id == bufs->ch_id) {
137 channel = &pme->channels[i];
138 break;
139 }
140 }
141 if (NULL == channel) {
142 CDBG_ERROR("%s: Channel object is NULL ", __func__);
143 return;
144 }
145 /* find preview stream */
146 for (i = 0; i < channel->num_streams; i++) {
147 if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_PREVIEW) {
148 p_stream = &channel->streams[i];
149 break;
150 }
151 }
152
153 if (NULL == p_stream) {
154 CDBG_ERROR("%s: cannot find preview stream", __func__);
155 return;
156 }
157
158 /* find preview frame */
159 for (i = 0; i < bufs->num_bufs; i++) {
160 if (bufs->bufs[i]->stream_id == p_stream->s_id) {
161 frame = bufs->bufs[i];
162 break;
163 }
164 }
165
166 if ( 0 < pme->fb_fd ) {
167 mm_app_overlay_display(pme, frame->fd);
168 }
169 #ifdef DUMP_PRV_IN_FILE
170 {
171 char file_name[64];
172 snprintf(file_name, sizeof(file_name), "P_C%d", pme->cam->camera_handle);
173 mm_app_dump_frame(frame, file_name, "yuv", frame->frame_idx);
174 }
175 #endif
176 if (pme->user_preview_cb) {
177 CDBG_ERROR("[DBG] %s, user defined own preview cb. calling it...", __func__);
178 pme->user_preview_cb(frame);
179 }
180 if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
181 bufs->ch_id,
182 frame)) {
183 CDBG_ERROR("%s: Failed in Preview Qbuf\n", __func__);
184 }
185 mm_app_cache_ops((mm_camera_app_meminfo_t *)frame->mem_info,
186 ION_IOC_INV_CACHES);
187
188 CDBG("%s: END\n", __func__);
189 }
190
mm_app_zsl_notify_cb(mm_camera_super_buf_t * bufs,void * user_data)191 static void mm_app_zsl_notify_cb(mm_camera_super_buf_t *bufs,
192 void *user_data)
193 {
194 int rc = MM_CAMERA_OK;
195 uint32_t i = 0;
196 mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
197 mm_camera_channel_t *channel = NULL;
198 mm_camera_stream_t *p_stream = NULL;
199 mm_camera_stream_t *m_stream = NULL;
200 mm_camera_stream_t *md_stream = NULL;
201 mm_camera_buf_def_t *p_frame = NULL;
202 mm_camera_buf_def_t *m_frame = NULL;
203 mm_camera_buf_def_t *md_frame = NULL;
204
205 CDBG("%s: BEGIN\n", __func__);
206
207 if (NULL == bufs || NULL == user_data) {
208 CDBG_ERROR("%s: bufs or user_data are not valid ", __func__);
209 return;
210 }
211
212 /* find channel */
213 for (i = 0; i < MM_CHANNEL_TYPE_MAX; i++) {
214 if (pme->channels[i].ch_id == bufs->ch_id) {
215 channel = &pme->channels[i];
216 break;
217 }
218 }
219 if (NULL == channel) {
220 CDBG_ERROR("%s: Wrong channel id (%d)", __func__, bufs->ch_id);
221 return;
222 }
223
224 /* find preview stream */
225 for (i = 0; i < channel->num_streams; i++) {
226 if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_PREVIEW) {
227 p_stream = &channel->streams[i];
228 break;
229 }
230 }
231 if (NULL == p_stream) {
232 CDBG_ERROR("%s: cannot find preview stream", __func__);
233 return;
234 }
235
236 /* find snapshot stream */
237 for (i = 0; i < channel->num_streams; i++) {
238 if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_SNAPSHOT) {
239 m_stream = &channel->streams[i];
240 break;
241 }
242 }
243 if (NULL == m_stream) {
244 CDBG_ERROR("%s: cannot find snapshot stream", __func__);
245 return;
246 }
247
248 /* find metadata stream */
249 for (i = 0; i < channel->num_streams; i++) {
250 if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_METADATA) {
251 md_stream = &channel->streams[i];
252 break;
253 }
254 }
255 if (NULL == md_stream) {
256 CDBG_ERROR("%s: cannot find metadata stream", __func__);
257 }
258
259 /* find preview frame */
260 for (i = 0; i < bufs->num_bufs; i++) {
261 if (bufs->bufs[i]->stream_id == p_stream->s_id) {
262 p_frame = bufs->bufs[i];
263 break;
264 }
265 }
266
267 if(md_stream) {
268 /* find metadata frame */
269 for (i = 0; i < bufs->num_bufs; i++) {
270 if (bufs->bufs[i]->stream_id == md_stream->s_id) {
271 md_frame = bufs->bufs[i];
272 break;
273 }
274 }
275 if (!md_frame) {
276 ALOGE("%s: md_frame is null\n", __func__);
277 return;
278 }
279 if (!pme->metadata) {
280 /* App will free the metadata */
281 pme->metadata = malloc(sizeof(metadata_buffer_t));
282 if (!pme->metadata) {
283 ALOGE("%s: not enough memory\n", __func__);
284 return;
285 }
286 }
287
288 memcpy(pme->metadata , md_frame->buffer, sizeof(metadata_buffer_t));
289 }
290 /* find snapshot frame */
291 for (i = 0; i < bufs->num_bufs; i++) {
292 if (bufs->bufs[i]->stream_id == m_stream->s_id) {
293 m_frame = bufs->bufs[i];
294 break;
295 }
296 }
297
298 if (!m_frame || !p_frame) {
299 CDBG_ERROR("%s: cannot find preview/snapshot frame", __func__);
300 return;
301 }
302
303 CDBG("%s: ZSL CB with fb_fd = %d, m_frame = %p, p_frame = %p \n",
304 __func__,
305 pme->fb_fd,
306 m_frame,
307 p_frame);
308
309 if ( 0 < pme->fb_fd ) {
310 mm_app_overlay_display(pme, p_frame->fd);
311 }/* else {
312 mm_app_dump_frame(p_frame, "zsl_preview", "yuv", p_frame->frame_idx);
313 mm_app_dump_frame(m_frame, "zsl_main", "yuv", m_frame->frame_idx);
314 }*/
315
316 if ( pme->enable_reproc && ( NULL != pme->reproc_stream ) ) {
317
318 if (NULL != md_frame) {
319 rc = mm_app_do_reprocess(pme,
320 m_frame,
321 md_frame->buf_idx,
322 bufs,
323 md_stream);
324
325 if (MM_CAMERA_OK != rc ) {
326 CDBG_ERROR("%s: reprocess failed rc = %d", __func__, rc);
327 }
328 } else {
329 CDBG_ERROR("%s: md_frame is null\n", __func__);
330 }
331
332 return;
333 }
334
335 if ( pme->encodeJpeg ) {
336 pme->jpeg_buf.buf.buffer = (uint8_t *)malloc(m_frame->frame_len);
337 if ( NULL == pme->jpeg_buf.buf.buffer ) {
338 CDBG_ERROR("%s: error allocating jpeg output buffer", __func__);
339 goto exit;
340 }
341
342 pme->jpeg_buf.buf.frame_len = m_frame->frame_len;
343 /* create a new jpeg encoding session */
344 rc = createEncodingSession(pme, m_stream, m_frame);
345 if (0 != rc) {
346 CDBG_ERROR("%s: error creating jpeg session", __func__);
347 free(pme->jpeg_buf.buf.buffer);
348 goto exit;
349 }
350
351 /* start jpeg encoding job */
352 rc = encodeData(pme, bufs, m_stream);
353 pme->encodeJpeg = 0;
354 } else {
355 if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
356 bufs->ch_id,
357 m_frame)) {
358 CDBG_ERROR("%s: Failed in main Qbuf\n", __func__);
359 }
360 mm_app_cache_ops((mm_camera_app_meminfo_t *)m_frame->mem_info,
361 ION_IOC_INV_CACHES);
362 }
363
364 exit:
365
366 if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
367 bufs->ch_id,
368 p_frame)) {
369 CDBG_ERROR("%s: Failed in preview Qbuf\n", __func__);
370 }
371 mm_app_cache_ops((mm_camera_app_meminfo_t *)p_frame->mem_info,
372 ION_IOC_INV_CACHES);
373
374 if(md_frame) {
375 if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
376 bufs->ch_id,
377 md_frame)) {
378 CDBG_ERROR("%s: Failed in metadata Qbuf\n", __func__);
379 }
380 mm_app_cache_ops((mm_camera_app_meminfo_t *)md_frame->mem_info,
381 ION_IOC_INV_CACHES);
382 }
383
384 CDBG("%s: END\n", __func__);
385 }
386
mm_app_add_metadata_stream(mm_camera_test_obj_t * test_obj,mm_camera_channel_t * channel,mm_camera_buf_notify_t stream_cb,void * userdata,uint8_t num_bufs)387 mm_camera_stream_t * mm_app_add_metadata_stream(mm_camera_test_obj_t *test_obj,
388 mm_camera_channel_t *channel,
389 mm_camera_buf_notify_t stream_cb,
390 void *userdata,
391 uint8_t num_bufs)
392 {
393 int rc = MM_CAMERA_OK;
394 mm_camera_stream_t *stream = NULL;
395 cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
396
397 stream = mm_app_add_stream(test_obj, channel);
398 if (NULL == stream) {
399 CDBG_ERROR("%s: add stream failed\n", __func__);
400 return NULL;
401 }
402
403 stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
404 stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
405 stream->s_config.mem_vtbl.clean_invalidate_buf =
406 mm_app_stream_clean_invalidate_buf;
407 stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
408 stream->s_config.mem_vtbl.user_data = (void *)stream;
409 stream->s_config.stream_cb = stream_cb;
410 stream->s_config.userdata = userdata;
411 stream->num_of_bufs = num_bufs;
412
413 stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
414 memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
415 stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_METADATA;
416 stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
417 stream->s_config.stream_info->fmt = DEFAULT_PREVIEW_FORMAT;
418 stream->s_config.stream_info->dim.width = sizeof(metadata_buffer_t);
419 stream->s_config.stream_info->dim.height = 1;
420 stream->s_config.padding_info = cam_cap->padding_info;
421
422 rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
423 if (MM_CAMERA_OK != rc) {
424 CDBG_ERROR("%s:config preview stream err=%d\n", __func__, rc);
425 return NULL;
426 }
427
428 return stream;
429 }
430
mm_app_add_preview_stream(mm_camera_test_obj_t * test_obj,mm_camera_channel_t * channel,mm_camera_buf_notify_t stream_cb,void * userdata,uint8_t num_bufs)431 mm_camera_stream_t * mm_app_add_preview_stream(mm_camera_test_obj_t *test_obj,
432 mm_camera_channel_t *channel,
433 mm_camera_buf_notify_t stream_cb,
434 void *userdata,
435 uint8_t num_bufs)
436 {
437 int rc = MM_CAMERA_OK;
438 mm_camera_stream_t *stream = NULL;
439 cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
440
441 stream = mm_app_add_stream(test_obj, channel);
442 if (NULL == stream) {
443 CDBG_ERROR("%s: add stream failed\n", __func__);
444 return NULL;
445 }
446 stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
447 stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
448 stream->s_config.mem_vtbl.clean_invalidate_buf =
449 mm_app_stream_clean_invalidate_buf;
450 stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
451 stream->s_config.mem_vtbl.user_data = (void *)stream;
452 stream->s_config.stream_cb = stream_cb;
453 stream->s_config.userdata = userdata;
454 stream->num_of_bufs = num_bufs;
455
456 stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
457 memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
458 stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_PREVIEW;
459 stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
460 stream->s_config.stream_info->fmt = DEFAULT_PREVIEW_FORMAT;
461
462 if ((test_obj->preview_resolution.user_input_display_width == 0) ||
463 ( test_obj->preview_resolution.user_input_display_height == 0)) {
464 stream->s_config.stream_info->dim.width = DEFAULT_PREVIEW_WIDTH;
465 stream->s_config.stream_info->dim.height = DEFAULT_PREVIEW_HEIGHT;
466 } else {
467 stream->s_config.stream_info->dim.width = test_obj->preview_resolution.user_input_display_width;
468 stream->s_config.stream_info->dim.height = test_obj->preview_resolution.user_input_display_height;
469 }
470
471 stream->s_config.padding_info = cam_cap->padding_info;
472
473 rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
474 if (MM_CAMERA_OK != rc) {
475 CDBG_ERROR("%s:config preview stream err=%d\n", __func__, rc);
476 return NULL;
477 }
478
479 return stream;
480 }
481
mm_app_add_raw_stream(mm_camera_test_obj_t * test_obj,mm_camera_channel_t * channel,mm_camera_buf_notify_t stream_cb,void * userdata,uint8_t num_bufs,uint8_t num_burst)482 mm_camera_stream_t * mm_app_add_raw_stream(mm_camera_test_obj_t *test_obj,
483 mm_camera_channel_t *channel,
484 mm_camera_buf_notify_t stream_cb,
485 void *userdata,
486 uint8_t num_bufs,
487 uint8_t num_burst)
488 {
489 int rc = MM_CAMERA_OK;
490 mm_camera_stream_t *stream = NULL;
491 cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
492
493 stream = mm_app_add_stream(test_obj, channel);
494 if (NULL == stream) {
495 CDBG_ERROR("%s: add stream failed\n", __func__);
496 return NULL;
497 }
498
499 stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
500 stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
501 stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
502 stream->s_config.mem_vtbl.user_data = (void *)stream;
503 stream->s_config.stream_cb = stream_cb;
504 stream->s_config.userdata = userdata;
505 stream->num_of_bufs = num_bufs;
506
507 stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
508 memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
509 stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_RAW;
510 if (num_burst == 0) {
511 stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
512 } else {
513 stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_BURST;
514 stream->s_config.stream_info->num_of_burst = num_burst;
515 }
516 stream->s_config.stream_info->fmt = test_obj->buffer_format;
517 if ( test_obj->buffer_width == 0 || test_obj->buffer_height == 0 ) {
518 stream->s_config.stream_info->dim.width = DEFAULT_SNAPSHOT_WIDTH;
519 stream->s_config.stream_info->dim.height = DEFAULT_SNAPSHOT_HEIGHT;
520 } else {
521 stream->s_config.stream_info->dim.width = (int32_t)test_obj->buffer_width;
522 stream->s_config.stream_info->dim.height = (int32_t)test_obj->buffer_height;
523 }
524 stream->s_config.padding_info = cam_cap->padding_info;
525
526 rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
527 if (MM_CAMERA_OK != rc) {
528 CDBG_ERROR("%s:config preview stream err=%d\n", __func__, rc);
529 return NULL;
530 }
531
532 return stream;
533 }
534
mm_app_add_snapshot_stream(mm_camera_test_obj_t * test_obj,mm_camera_channel_t * channel,mm_camera_buf_notify_t stream_cb,void * userdata,uint8_t num_bufs,uint8_t num_burst)535 mm_camera_stream_t * mm_app_add_snapshot_stream(mm_camera_test_obj_t *test_obj,
536 mm_camera_channel_t *channel,
537 mm_camera_buf_notify_t stream_cb,
538 void *userdata,
539 uint8_t num_bufs,
540 uint8_t num_burst)
541 {
542 int rc = MM_CAMERA_OK;
543 mm_camera_stream_t *stream = NULL;
544 cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
545
546 stream = mm_app_add_stream(test_obj, channel);
547 if (NULL == stream) {
548 CDBG_ERROR("%s: add stream failed\n", __func__);
549 return NULL;
550 }
551
552 stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
553 stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
554 stream->s_config.mem_vtbl.clean_invalidate_buf =
555 mm_app_stream_clean_invalidate_buf;
556 stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
557 stream->s_config.mem_vtbl.user_data = (void *)stream;
558 stream->s_config.stream_cb = stream_cb;
559 stream->s_config.userdata = userdata;
560 stream->num_of_bufs = num_bufs;
561
562 stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
563 memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
564 stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_SNAPSHOT;
565 if (num_burst == 0) {
566 stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
567 } else {
568 stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_BURST;
569 stream->s_config.stream_info->num_of_burst = num_burst;
570 }
571 stream->s_config.stream_info->fmt = DEFAULT_SNAPSHOT_FORMAT;
572 if ( test_obj->buffer_width == 0 || test_obj->buffer_height == 0 ) {
573 stream->s_config.stream_info->dim.width = DEFAULT_SNAPSHOT_WIDTH;
574 stream->s_config.stream_info->dim.height = DEFAULT_SNAPSHOT_HEIGHT;
575 } else {
576 stream->s_config.stream_info->dim.width = (int32_t)test_obj->buffer_width;
577 stream->s_config.stream_info->dim.height = (int32_t)test_obj->buffer_height;
578 }
579 stream->s_config.padding_info = cam_cap->padding_info;
580
581 rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
582 if (MM_CAMERA_OK != rc) {
583 CDBG_ERROR("%s:config preview stream err=%d\n", __func__, rc);
584 return NULL;
585 }
586
587 return stream;
588 }
589
mm_app_add_preview_channel(mm_camera_test_obj_t * test_obj)590 mm_camera_channel_t * mm_app_add_preview_channel(mm_camera_test_obj_t *test_obj)
591 {
592 mm_camera_channel_t *channel = NULL;
593 mm_camera_stream_t *stream = NULL;
594
595 channel = mm_app_add_channel(test_obj,
596 MM_CHANNEL_TYPE_PREVIEW,
597 NULL,
598 NULL,
599 NULL);
600 if (NULL == channel) {
601 CDBG_ERROR("%s: add channel failed", __func__);
602 return NULL;
603 }
604
605 stream = mm_app_add_preview_stream(test_obj,
606 channel,
607 mm_app_preview_notify_cb,
608 (void *)test_obj,
609 PREVIEW_BUF_NUM);
610 if (NULL == stream) {
611 CDBG_ERROR("%s: add stream failed\n", __func__);
612 mm_app_del_channel(test_obj, channel);
613 return NULL;
614 }
615
616 return channel;
617 }
618
mm_app_stop_and_del_channel(mm_camera_test_obj_t * test_obj,mm_camera_channel_t * channel)619 int mm_app_stop_and_del_channel(mm_camera_test_obj_t *test_obj,
620 mm_camera_channel_t *channel)
621 {
622 int rc = MM_CAMERA_OK;
623 mm_camera_stream_t *stream = NULL;
624 uint8_t i;
625
626 rc = mm_app_stop_channel(test_obj, channel);
627 if (MM_CAMERA_OK != rc) {
628 CDBG_ERROR("%s:Stop Preview failed rc=%d\n", __func__, rc);
629 }
630
631 if (channel->num_streams <= MAX_STREAM_NUM_IN_BUNDLE) {
632 for (i = 0; i < channel->num_streams; i++) {
633 stream = &channel->streams[i];
634 rc = mm_app_del_stream(test_obj, channel, stream);
635 if (MM_CAMERA_OK != rc) {
636 CDBG_ERROR("%s:del stream(%d) failed rc=%d\n", __func__, i, rc);
637 }
638 }
639 } else {
640 CDBG_ERROR("%s: num_streams = %d. Should not be more than %d\n",
641 __func__, channel->num_streams, MAX_STREAM_NUM_IN_BUNDLE);
642 }
643 rc = mm_app_del_channel(test_obj, channel);
644 if (MM_CAMERA_OK != rc) {
645 CDBG_ERROR("%s:delete channel failed rc=%d\n", __func__, rc);
646 }
647
648 return rc;
649 }
650
mm_app_start_preview(mm_camera_test_obj_t * test_obj)651 int mm_app_start_preview(mm_camera_test_obj_t *test_obj)
652 {
653 int rc = MM_CAMERA_OK;
654 mm_camera_channel_t *channel = NULL;
655 mm_camera_stream_t *stream = NULL;
656 mm_camera_stream_t *s_metadata = NULL;
657 uint8_t i;
658
659 channel = mm_app_add_preview_channel(test_obj);
660 if (NULL == channel) {
661 CDBG_ERROR("%s: add channel failed", __func__);
662 return -MM_CAMERA_E_GENERAL;
663 }
664
665 s_metadata = mm_app_add_metadata_stream(test_obj,
666 channel,
667 mm_app_metadata_notify_cb,
668 (void *)test_obj,
669 PREVIEW_BUF_NUM);
670 if (NULL == s_metadata) {
671 CDBG_ERROR("%s: add metadata stream failed\n", __func__);
672 mm_app_del_channel(test_obj, channel);
673 return rc;
674 }
675
676 rc = mm_app_start_channel(test_obj, channel);
677 if (MM_CAMERA_OK != rc) {
678 CDBG_ERROR("%s:start preview failed rc=%d\n", __func__, rc);
679 if (channel->num_streams <= MAX_STREAM_NUM_IN_BUNDLE) {
680 for (i = 0; i < channel->num_streams; i++) {
681 stream = &channel->streams[i];
682 mm_app_del_stream(test_obj, channel, stream);
683 }
684 }
685 mm_app_del_channel(test_obj, channel);
686 return rc;
687 }
688
689 return rc;
690 }
691
mm_app_stop_preview(mm_camera_test_obj_t * test_obj)692 int mm_app_stop_preview(mm_camera_test_obj_t *test_obj)
693 {
694 int rc = MM_CAMERA_OK;
695
696 mm_camera_channel_t *channel =
697 mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_PREVIEW);
698
699 rc = mm_app_stop_and_del_channel(test_obj, channel);
700 if (MM_CAMERA_OK != rc) {
701 CDBG_ERROR("%s:Stop Preview failed rc=%d\n", __func__, rc);
702 }
703
704 return rc;
705 }
706
mm_app_start_preview_zsl(mm_camera_test_obj_t * test_obj)707 int mm_app_start_preview_zsl(mm_camera_test_obj_t *test_obj)
708 {
709 int32_t rc = MM_CAMERA_OK;
710 mm_camera_channel_t *channel = NULL;
711 mm_camera_stream_t *s_preview = NULL;
712 mm_camera_stream_t *s_metadata = NULL;
713 mm_camera_stream_t *s_main = NULL;
714 mm_camera_channel_attr_t attr;
715
716 memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
717 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
718 attr.look_back = 2;
719 attr.post_frame_skip = 0;
720 attr.water_mark = 2;
721 attr.max_unmatched_frames = 3;
722 channel = mm_app_add_channel(test_obj,
723 MM_CHANNEL_TYPE_ZSL,
724 &attr,
725 mm_app_zsl_notify_cb,
726 test_obj);
727 if (NULL == channel) {
728 CDBG_ERROR("%s: add channel failed", __func__);
729 return -MM_CAMERA_E_GENERAL;
730 }
731
732 s_preview = mm_app_add_preview_stream(test_obj,
733 channel,
734 mm_app_preview_notify_cb,
735 (void *)test_obj,
736 PREVIEW_BUF_NUM);
737 if (NULL == s_preview) {
738 CDBG_ERROR("%s: add preview stream failed\n", __func__);
739 mm_app_del_channel(test_obj, channel);
740 return rc;
741 }
742
743 s_metadata = mm_app_add_metadata_stream(test_obj,
744 channel,
745 mm_app_metadata_notify_cb,
746 (void *)test_obj,
747 PREVIEW_BUF_NUM);
748 if (NULL == s_metadata) {
749 CDBG_ERROR("%s: add metadata stream failed\n", __func__);
750 mm_app_del_channel(test_obj, channel);
751 return rc;
752 }
753
754 s_main = mm_app_add_snapshot_stream(test_obj,
755 channel,
756 NULL,
757 NULL,
758 PREVIEW_BUF_NUM,
759 0);
760 if (NULL == s_main) {
761 CDBG_ERROR("%s: add main snapshot stream failed\n", __func__);
762 mm_app_del_stream(test_obj, channel, s_preview);
763 mm_app_del_channel(test_obj, channel);
764 return rc;
765 }
766
767 rc = mm_app_start_channel(test_obj, channel);
768 if (MM_CAMERA_OK != rc) {
769 CDBG_ERROR("%s:start zsl failed rc=%d\n", __func__, rc);
770 mm_app_del_stream(test_obj, channel, s_preview);
771 mm_app_del_stream(test_obj, channel, s_metadata);
772 mm_app_del_stream(test_obj, channel, s_main);
773 mm_app_del_channel(test_obj, channel);
774 return rc;
775 }
776
777 if ( test_obj->enable_reproc ) {
778 if ( NULL == mm_app_add_reprocess_channel(test_obj, s_main) ) {
779 CDBG_ERROR("%s: Reprocess channel failed to initialize \n", __func__);
780 mm_app_del_stream(test_obj, channel, s_preview);
781 #ifdef USE_METADATA_STREAM
782 mm_app_del_stream(test_obj, channel, s_metadata);
783 #endif
784 mm_app_del_stream(test_obj, channel, s_main);
785 mm_app_del_channel(test_obj, channel);
786 return rc;
787 }
788 rc = mm_app_start_reprocess(test_obj);
789 if (MM_CAMERA_OK != rc) {
790 CDBG_ERROR("%s: reprocess start failed rc=%d\n", __func__, rc);
791 mm_app_del_stream(test_obj, channel, s_preview);
792 #ifdef USE_METADATA_STREAM
793 mm_app_del_stream(test_obj, channel, s_metadata);
794 #endif
795 mm_app_del_stream(test_obj, channel, s_main);
796 mm_app_del_channel(test_obj, channel);
797 return rc;
798 }
799 }
800
801 return rc;
802 }
803
mm_app_stop_preview_zsl(mm_camera_test_obj_t * test_obj)804 int mm_app_stop_preview_zsl(mm_camera_test_obj_t *test_obj)
805 {
806 int rc = MM_CAMERA_OK;
807
808 mm_camera_channel_t *channel =
809 mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_ZSL);
810
811 rc = mm_app_stop_and_del_channel(test_obj, channel);
812 if (MM_CAMERA_OK != rc) {
813 CDBG_ERROR("%s:Stop Preview failed rc=%d\n", __func__, rc);
814 }
815
816 if ( test_obj->enable_reproc ) {
817 rc |= mm_app_stop_reprocess(test_obj);
818 }
819
820 return rc;
821 }
822
mm_app_initialize_fb(mm_camera_test_obj_t * test_obj)823 int mm_app_initialize_fb(mm_camera_test_obj_t *test_obj)
824 {
825 int rc = MM_CAMERA_OK;
826 int brightness_fd;
827 const char brightness_level[] = BACKLIGHT_LEVEL;
828 void *fb_base = NULL;
829
830 assert( ( NULL != test_obj ) && ( 0 == test_obj->fb_fd ) );
831
832 test_obj->fb_fd = open(FB_PATH, O_RDWR);
833 if ( 0 > test_obj->fb_fd ) {
834 CDBG_ERROR("%s: FB device open failed rc=%d, %s\n",
835 __func__,
836 -errno,
837 strerror(errno));
838 rc = -errno;
839 goto FAIL;
840 }
841
842 rc = ioctl(test_obj->fb_fd, FBIOGET_VSCREENINFO, &test_obj->vinfo);
843 if ( MM_CAMERA_OK != rc ) {
844 CDBG_ERROR("%s: Can not retrieve screen info rc=%d, %s\n",
845 __func__,
846 -errno,
847 strerror(errno));
848 rc = -errno;
849 goto FAIL;
850 }
851
852 if ( ( 0 == test_obj->vinfo.yres_virtual ) ||
853 ( 0 == test_obj->vinfo.yres ) ||
854 ( test_obj->vinfo.yres > test_obj->vinfo.yres_virtual ) ) {
855 CDBG_ERROR("%s: Invalid FB virtual yres: %d, yres: %d\n",
856 __func__,
857 test_obj->vinfo.yres_virtual,
858 test_obj->vinfo.yres);
859 rc = MM_CAMERA_E_GENERAL;
860 goto FAIL;
861 }
862
863 if ( ( 0 == test_obj->vinfo.xres_virtual ) ||
864 ( 0 == test_obj->vinfo.xres ) ||
865 ( test_obj->vinfo.xres > test_obj->vinfo.xres_virtual ) ) {
866 CDBG_ERROR("%s: Invalid FB virtual xres: %d, xres: %d\n",
867 __func__,
868 test_obj->vinfo.xres_virtual,
869 test_obj->vinfo.xres);
870 rc = MM_CAMERA_E_GENERAL;
871 goto FAIL;
872 }
873
874 brightness_fd = open(BACKLIGHT_CONTROL, O_RDWR);
875 if ( brightness_fd >= 0 ) {
876 write(brightness_fd, brightness_level, strlen(brightness_level));
877 close(brightness_fd);
878 }
879
880 test_obj->slice_size = test_obj->vinfo.xres * ( test_obj->vinfo.yres - 1 ) * DEFAULT_OV_FORMAT_BPP;
881 memset(&test_obj->data_overlay, 0, sizeof(struct mdp_overlay));
882 test_obj->data_overlay.src.width = test_obj->buffer_width;
883 test_obj->data_overlay.src.height = test_obj->buffer_height;
884 test_obj->data_overlay.src_rect.w = test_obj->buffer_width;
885 test_obj->data_overlay.src_rect.h = test_obj->buffer_height;
886 test_obj->data_overlay.dst_rect.w = test_obj->buffer_width;
887 test_obj->data_overlay.dst_rect.h = test_obj->buffer_height;
888 test_obj->data_overlay.src.format = DEFAULT_OV_FORMAT;
889 test_obj->data_overlay.src_rect.x = 0;
890 test_obj->data_overlay.src_rect.y = 0;
891 test_obj->data_overlay.dst_rect.x = 0;
892 test_obj->data_overlay.dst_rect.y = 0;
893 test_obj->data_overlay.z_order = 2;
894 test_obj->data_overlay.alpha = 0x80;
895 test_obj->data_overlay.transp_mask = 0xffe0;
896 test_obj->data_overlay.flags = MDP_FLIP_LR | MDP_FLIP_UD;
897
898 // Map and clear FB portion
899 fb_base = mmap(0,
900 test_obj->slice_size,
901 PROT_WRITE,
902 MAP_SHARED,
903 test_obj->fb_fd,
904 0);
905 if ( MAP_FAILED == fb_base ) {
906 CDBG_ERROR("%s: ( Error while memory mapping frame buffer %s",
907 __func__,
908 strerror(errno));
909 rc = -errno;
910 goto FAIL;
911 }
912
913 memset(fb_base, 0, test_obj->slice_size);
914
915 if (ioctl(test_obj->fb_fd, FBIOPAN_DISPLAY, &test_obj->vinfo) < 0) {
916 CDBG_ERROR("%s : FBIOPAN_DISPLAY failed!", __func__);
917 rc = -errno;
918 goto FAIL;
919 }
920
921 munmap(fb_base, test_obj->slice_size);
922 test_obj->data_overlay.id = (uint32_t)MSMFB_NEW_REQUEST;
923 rc = ioctl(test_obj->fb_fd, MSMFB_OVERLAY_SET, &test_obj->data_overlay);
924 if (rc < 0) {
925 CDBG_ERROR("%s : MSMFB_OVERLAY_SET failed! err=%d\n",
926 __func__,
927 test_obj->data_overlay.id);
928 return MM_CAMERA_E_GENERAL;
929 }
930 CDBG_ERROR("%s: Overlay set with overlay id: %d", __func__, test_obj->data_overlay.id);
931
932 return rc;
933
934 FAIL:
935
936 if ( 0 < test_obj->fb_fd ) {
937 close(test_obj->fb_fd);
938 }
939
940 return rc;
941 }
942
mm_app_close_fb(mm_camera_test_obj_t * test_obj)943 int mm_app_close_fb(mm_camera_test_obj_t *test_obj)
944 {
945 int rc = MM_CAMERA_OK;
946
947 assert( ( NULL != test_obj ) && ( 0 < test_obj->fb_fd ) );
948
949 if (ioctl(test_obj->fb_fd, MSMFB_OVERLAY_UNSET, &test_obj->data_overlay.id)) {
950 CDBG_ERROR("\nERROR! MSMFB_OVERLAY_UNSET failed! (Line %d)\n", __LINE__);
951 }
952
953 if (ioctl(test_obj->fb_fd, FBIOPAN_DISPLAY, &test_obj->vinfo) < 0) {
954 CDBG_ERROR("ERROR: FBIOPAN_DISPLAY failed! line=%d\n", __LINE__);
955 }
956
957 close(test_obj->fb_fd);
958 test_obj->fb_fd = -1;
959
960 return rc;
961 }
962
memset16(void * pDst,uint16_t value,int count)963 void memset16(void *pDst, uint16_t value, int count)
964 {
965 uint16_t *ptr = pDst;
966 while (count--)
967 *ptr++ = value;
968 }
969
mm_app_overlay_display(mm_camera_test_obj_t * test_obj,int bufferFd)970 int mm_app_overlay_display(mm_camera_test_obj_t *test_obj, int bufferFd)
971 {
972 int rc = MM_CAMERA_OK;
973 struct msmfb_overlay_data ovdata;
974
975
976 memset(&ovdata, 0, sizeof(struct msmfb_overlay_data));
977 ovdata.id = test_obj->data_overlay.id;
978 ovdata.data.memory_id = bufferFd;
979
980 if (ioctl(test_obj->fb_fd, MSMFB_OVERLAY_PLAY, &ovdata)) {
981 CDBG_ERROR("%s : MSMFB_OVERLAY_PLAY failed!", __func__);
982 return MM_CAMERA_E_GENERAL;
983 }
984
985 if (ioctl(test_obj->fb_fd, FBIOPAN_DISPLAY, &test_obj->vinfo) < 0) {
986 CDBG_ERROR("%s : FBIOPAN_DISPLAY failed!", __func__);
987 return MM_CAMERA_E_GENERAL;
988 }
989
990 return rc;
991 }
992