1 /* Copyright (c) 2012-2014 The Linux Foundataion. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29
30 #define LOG_TAG "QCameraChannel"
31
32 #include <utils/Errors.h>
33 #include "QCameraParameters.h"
34 #include "QCamera2HWI.h"
35 #include "QCameraChannel.h"
36
37 using namespace android;
38
39 namespace qcamera {
40
41 /*===========================================================================
42 * FUNCTION : QCameraChannel
43 *
44 * DESCRIPTION: constrcutor of QCameraChannel
45 *
46 * PARAMETERS :
47 * @cam_handle : camera handle
48 * @cam_ops : ptr to camera ops table
49 *
50 * RETURN : none
51 *==========================================================================*/
QCameraChannel(uint32_t cam_handle,mm_camera_ops_t * cam_ops)52 QCameraChannel::QCameraChannel(uint32_t cam_handle,
53 mm_camera_ops_t *cam_ops)
54 {
55 m_camHandle = cam_handle;
56 m_camOps = cam_ops;
57 m_bIsActive = false;
58 m_bAllowDynBufAlloc = false;
59
60 m_handle = 0;
61 m_numStreams = 0;
62 memset(mStreams, 0, sizeof(mStreams));
63 }
64
65 /*===========================================================================
66 * FUNCTION : QCameraChannel
67 *
68 * DESCRIPTION: default constrcutor of QCameraChannel
69 *
70 * PARAMETERS : none
71 *
72 * RETURN : none
73 *==========================================================================*/
QCameraChannel()74 QCameraChannel::QCameraChannel()
75 {
76 m_camHandle = 0;
77 m_camOps = NULL;
78 m_bIsActive = false;
79
80 m_handle = 0;
81 m_numStreams = 0;
82 memset(mStreams, 0, sizeof(mStreams));
83 }
84
85 /*===========================================================================
86 * FUNCTION : ~QCameraChannel
87 *
88 * DESCRIPTION: destructor of QCameraChannel
89 *
90 * PARAMETERS : none
91 *
92 * RETURN : none
93 *==========================================================================*/
~QCameraChannel()94 QCameraChannel::~QCameraChannel()
95 {
96 if (m_bIsActive) {
97 stop();
98 }
99
100 for (int i = 0; i < m_numStreams; i++) {
101 if (mStreams[i] != NULL) {
102 delete mStreams[i];
103 mStreams[i] = 0;
104 }
105 }
106 m_numStreams = 0;
107 m_camOps->delete_channel(m_camHandle, m_handle);
108 m_handle = 0;
109 }
110
111 /*===========================================================================
112 * FUNCTION : deleteChannel
113 *
114 * DESCRIPTION: deletes a camera channel
115 *
116 * PARAMETERS : none
117 *
118 * RETURN : none
119 *==========================================================================*/
deleteChannel()120 void QCameraChannel::deleteChannel()
121 {
122 if (m_bIsActive) {
123 stop();
124 }
125
126 for (int i = 0; i < m_numStreams; i++) {
127 if (mStreams[i] != NULL) {
128 mStreams[i]->deleteStream();
129 }
130 }
131 m_camOps->delete_channel(m_camHandle, m_handle);
132 }
133
134 /*===========================================================================
135 * FUNCTION : init
136 *
137 * DESCRIPTION: initialization of channel
138 *
139 * PARAMETERS :
140 * @attr : channel bundle attribute setting
141 * @dataCB : data notify callback
142 * @userData: user data ptr
143 *
144 * RETURN : int32_t type of status
145 * NO_ERROR -- success
146 * none-zero failure code
147 *==========================================================================*/
init(mm_camera_channel_attr_t * attr,mm_camera_buf_notify_t dataCB,void * userData)148 int32_t QCameraChannel::init(mm_camera_channel_attr_t *attr,
149 mm_camera_buf_notify_t dataCB,
150 void *userData)
151 {
152 m_handle = m_camOps->add_channel(m_camHandle,
153 attr,
154 dataCB,
155 userData);
156 if (m_handle == 0) {
157 ALOGE("%s: Add channel failed", __func__);
158 return UNKNOWN_ERROR;
159 }
160 return NO_ERROR;
161 }
162
163 /*===========================================================================
164 * FUNCTION : addStream
165 *
166 * DESCRIPTION: add a stream into channel
167 *
168 * PARAMETERS :
169 * @allocator : stream related buffer allocator
170 * @streamInfoBuf : ptr to buf that constains stream info
171 * @minStreamBufNum: number of stream buffers needed
172 * @paddingInfo : padding information
173 * @stream_cb : stream data notify callback
174 * @userdata : user data ptr
175 * @bDynAllocBuf : flag indicating if allow allocate buffers in 2 steps
176 *
177 * RETURN : int32_t type of status
178 * NO_ERROR -- success
179 * none-zero failure code
180 *==========================================================================*/
addStream(QCameraAllocator & allocator,QCameraHeapMemory * streamInfoBuf,uint8_t minStreamBufNum,cam_padding_info_t * paddingInfo,stream_cb_routine stream_cb,void * userdata,bool bDynAllocBuf,bool bDeffAlloc)181 int32_t QCameraChannel::addStream(QCameraAllocator &allocator,
182 QCameraHeapMemory *streamInfoBuf,
183 uint8_t minStreamBufNum,
184 cam_padding_info_t *paddingInfo,
185 stream_cb_routine stream_cb,
186 void *userdata,
187 bool bDynAllocBuf,
188 bool bDeffAlloc)
189 {
190 int32_t rc = NO_ERROR;
191 if (m_numStreams >= MAX_STREAM_NUM_IN_BUNDLE) {
192 ALOGE("%s: stream number (%d) exceeds max limit (%d)",
193 __func__, m_numStreams, MAX_STREAM_NUM_IN_BUNDLE);
194 return BAD_VALUE;
195 }
196 QCameraStream *pStream = new QCameraStream(allocator,
197 m_camHandle,
198 m_handle,
199 m_camOps,
200 paddingInfo,
201 bDeffAlloc);
202 if (pStream == NULL) {
203 ALOGE("%s: No mem for Stream", __func__);
204 return NO_MEMORY;
205 }
206
207 rc = pStream->init(streamInfoBuf, minStreamBufNum,
208 stream_cb, userdata, bDynAllocBuf);
209 if (rc == 0) {
210 mStreams[m_numStreams] = pStream;
211 m_numStreams++;
212 } else {
213 delete pStream;
214 }
215 return rc;
216 }
217 /*===========================================================================
218 * FUNCTION : config
219 *
220 * DESCRIPTION: Configure any deffered channel streams
221 *
222 * PARAMETERS : None
223 *
224 * RETURN : int32_t type of status
225 * NO_ERROR -- success
226 * none-zero failure code
227 *==========================================================================*/
config()228 int32_t QCameraChannel::config()
229 {
230 int32_t rc = NO_ERROR;
231
232 for (int i = 0; i < m_numStreams; ++i) {
233 if ( mStreams[i]->isDeffered() ) {
234 rc = mStreams[i]->configStream();
235 if (rc != NO_ERROR) {
236 break;
237 }
238 }
239 }
240
241 return rc;
242 }
243
244 /*===========================================================================
245 * FUNCTION : start
246 *
247 * DESCRIPTION: start channel, which will start all streams belong to this channel
248 *
249 * PARAMETERS : None
250 *
251 * RETURN : int32_t type of status
252 * NO_ERROR -- success
253 * none-zero failure code
254 *==========================================================================*/
start()255 int32_t QCameraChannel::start()
256 {
257 int32_t rc = NO_ERROR;
258
259 if (m_numStreams > 1) {
260 // there is more than one stream in the channel
261 // we need to notify mctl that all streams in this channel need to be bundled
262 cam_bundle_config_t bundleInfo;
263 memset(&bundleInfo, 0, sizeof(bundleInfo));
264 rc = m_camOps->get_bundle_info(m_camHandle, m_handle, &bundleInfo);
265 if (rc != NO_ERROR) {
266 ALOGE("%s: get_bundle_info failed", __func__);
267 return rc;
268 }
269 if (bundleInfo.num_of_streams > 1) {
270 for (int i = 0; i < bundleInfo.num_of_streams; i++) {
271 QCameraStream *pStream = getStreamByServerID(bundleInfo.stream_ids[i]);
272 if (pStream != NULL) {
273 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) {
274 // Skip metadata for reprocess now because PP module cannot handle meta data
275 // May need furthur discussion if Imaginglib need meta data
276 continue;
277 }
278
279 cam_stream_parm_buffer_t param;
280 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t));
281 param.type = CAM_STREAM_PARAM_TYPE_SET_BUNDLE_INFO;
282 param.bundleInfo = bundleInfo;
283 rc = pStream->setParameter(param);
284 if (rc != NO_ERROR) {
285 ALOGE("%s: stream setParameter for set bundle failed", __func__);
286 return rc;
287 }
288 }
289 }
290 }
291 }
292
293 for (int i = 0; i < m_numStreams; i++) {
294 if (mStreams[i] != NULL) {
295 mStreams[i]->start();
296 }
297 }
298 rc = m_camOps->start_channel(m_camHandle, m_handle);
299
300 if (rc != NO_ERROR) {
301 for (int i = 0; i < m_numStreams; i++) {
302 if (mStreams[i] != NULL) {
303 mStreams[i]->stop();
304 }
305 }
306 } else {
307 m_bIsActive = true;
308 for (int i = 0; i < m_numStreams; i++) {
309 if (mStreams[i] != NULL) {
310 mStreams[i]->cond_signal();
311 }
312 }
313 }
314
315 return rc;
316 }
317
318 /*===========================================================================
319 * FUNCTION : stop
320 *
321 * DESCRIPTION: stop a channel, which will stop all streams belong to this channel
322 *
323 * PARAMETERS : none
324 *
325 * RETURN : int32_t type of status
326 * NO_ERROR -- success
327 * none-zero failure code
328 *==========================================================================*/
stop()329 int32_t QCameraChannel::stop()
330 {
331 int32_t rc = NO_ERROR;
332 for (int i = 0; i < m_numStreams; i++) {
333 if (mStreams[i] != NULL) {
334 mStreams[i]->stop();
335 }
336 }
337
338 rc = m_camOps->stop_channel(m_camHandle, m_handle);
339
340 m_bIsActive = false;
341 return rc;
342 }
343
344 /*===========================================================================
345 * FUNCTION : bufDone
346 *
347 * DESCRIPTION: return a stream buf back to kernel
348 *
349 * PARAMETERS :
350 * @recvd_frame : stream buf frame to be returned
351 *
352 * RETURN : int32_t type of status
353 * NO_ERROR -- success
354 * none-zero failure code
355 *==========================================================================*/
bufDone(mm_camera_super_buf_t * recvd_frame)356 int32_t QCameraChannel::bufDone(mm_camera_super_buf_t *recvd_frame)
357 {
358 int32_t rc = NO_ERROR;
359 for (int i = 0; i < recvd_frame->num_bufs; i++) {
360 if (recvd_frame->bufs[i] != NULL) {
361 for (int j = 0; j < m_numStreams; j++) {
362 if (mStreams[j] != NULL &&
363 mStreams[j]->getMyHandle() == recvd_frame->bufs[i]->stream_id) {
364 rc = mStreams[j]->bufDone(recvd_frame->bufs[i]->buf_idx);
365 break; // break loop j
366 }
367 }
368 }
369 }
370
371 return rc;
372 }
373
374 /*===========================================================================
375 * FUNCTION : processZoomDone
376 *
377 * DESCRIPTION: process zoom done event
378 *
379 * PARAMETERS :
380 * @previewWindoe : ptr to preview window ops table, needed to set preview
381 * crop information
382 * @crop_info : crop info as a result of zoom operation
383 *
384 * RETURN : int32_t type of status
385 * NO_ERROR -- success
386 * none-zero failure code
387 *==========================================================================*/
processZoomDone(preview_stream_ops_t * previewWindow,cam_crop_data_t & crop_info)388 int32_t QCameraChannel::processZoomDone(preview_stream_ops_t *previewWindow,
389 cam_crop_data_t &crop_info)
390 {
391 int32_t rc = NO_ERROR;
392 for (int i = 0; i < m_numStreams; i++) {
393 if (mStreams[i] != NULL) {
394 rc = mStreams[i]->processZoomDone(previewWindow, crop_info);
395 }
396 }
397 return rc;
398 }
399
400 /*===========================================================================
401 * FUNCTION : getStreamByHandle
402 *
403 * DESCRIPTION: return stream object by stream handle
404 *
405 * PARAMETERS :
406 * @streamHandle : stream handle
407 *
408 * RETURN : stream object. NULL if not found
409 *==========================================================================*/
getStreamByHandle(uint32_t streamHandle)410 QCameraStream *QCameraChannel::getStreamByHandle(uint32_t streamHandle)
411 {
412 for (int i = 0; i < m_numStreams; i++) {
413 if (mStreams[i] != NULL && mStreams[i]->getMyHandle() == streamHandle) {
414 return mStreams[i];
415 }
416 }
417 return NULL;
418 }
419
420 /*===========================================================================
421 * FUNCTION : getStreamByServerID
422 *
423 * DESCRIPTION: return stream object by stream server ID from daemon
424 *
425 * PARAMETERS :
426 * @serverID : stream server ID
427 *
428 * RETURN : stream object. NULL if not found
429 *==========================================================================*/
getStreamByServerID(uint32_t serverID)430 QCameraStream *QCameraChannel::getStreamByServerID(uint32_t serverID)
431 {
432 for (int i = 0; i < m_numStreams; i++) {
433 if (mStreams[i] != NULL && mStreams[i]->getMyServerID() == serverID) {
434 return mStreams[i];
435 }
436 }
437 return NULL;
438 }
439
440 /*===========================================================================
441 * FUNCTION : getStreamByIndex
442 *
443 * DESCRIPTION: return stream object by index of streams in the channel
444 *
445 * PARAMETERS :
446 * @index : index of stream in the channel
447 *
448 * RETURN : stream object. NULL if not found
449 *==========================================================================*/
getStreamByIndex(uint8_t index)450 QCameraStream *QCameraChannel::getStreamByIndex(uint8_t index)
451 {
452 if (index >= MAX_STREAM_NUM_IN_BUNDLE) {
453 return NULL;
454 }
455
456 if (index < m_numStreams) {
457 return mStreams[index];
458 }
459 return NULL;
460 }
461
462 /*===========================================================================
463 * FUNCTION : UpdateStreamBasedParameters
464 *
465 * DESCRIPTION: update any stream based settings from parameters
466 *
467 * PARAMETERS :
468 * @param : reference to parameters object
469 *
470 * RETURN : int32_t type of status
471 * NO_ERROR -- success
472 * none-zero failure code
473 *==========================================================================*/
UpdateStreamBasedParameters(QCameraParameters & param)474 int32_t QCameraChannel::UpdateStreamBasedParameters(QCameraParameters ¶m)
475 {
476 int32_t rc = NO_ERROR;
477 if (param.isPreviewFlipChanged()) {
478 // try to find preview stream
479 for (int i = 0; i < MAX_STREAM_NUM_IN_BUNDLE; i++) {
480 if (mStreams[i] != NULL &&
481 (mStreams[i]->isTypeOf(CAM_STREAM_TYPE_PREVIEW) ||
482 (mStreams[i]->isOrignalTypeOf(CAM_STREAM_TYPE_PREVIEW))) ) {
483 cam_stream_parm_buffer_t param_buf;
484 memset(¶m_buf, 0, sizeof(cam_stream_parm_buffer_t));
485 param_buf.type = CAM_STREAM_PARAM_TYPE_SET_FLIP;
486 param_buf.flipInfo.flip_mask = param.getFlipMode(CAM_STREAM_TYPE_PREVIEW);
487 rc = mStreams[i]->setParameter(param_buf);
488 if (rc != NO_ERROR) {
489 ALOGE("%s: set preview stream flip failed", __func__);
490 }
491 }
492 }
493 }
494 if (param.isVideoFlipChanged()) {
495 // try to find video stream
496 for (int i = 0; i < MAX_STREAM_NUM_IN_BUNDLE; i++) {
497 if (mStreams[i] != NULL &&
498 (mStreams[i]->isTypeOf(CAM_STREAM_TYPE_VIDEO) ||
499 (mStreams[i]->isOrignalTypeOf(CAM_STREAM_TYPE_VIDEO))) ) {
500 cam_stream_parm_buffer_t param_buf;
501 memset(¶m_buf, 0, sizeof(cam_stream_parm_buffer_t));
502 param_buf.type = CAM_STREAM_PARAM_TYPE_SET_FLIP;
503 param_buf.flipInfo.flip_mask = param.getFlipMode(CAM_STREAM_TYPE_VIDEO);
504 rc = mStreams[i]->setParameter(param_buf);
505 if (rc != NO_ERROR) {
506 ALOGE("%s: set video stream flip failed", __func__);
507 }
508 }
509 }
510 }
511 if (param.isSnapshotFlipChanged()) {
512 // try to find snapshot/postview stream
513 for (int i = 0; i < MAX_STREAM_NUM_IN_BUNDLE; i++) {
514 if (mStreams[i] != NULL &&
515 (mStreams[i]->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT) ||
516 mStreams[i]->isOrignalTypeOf(CAM_STREAM_TYPE_SNAPSHOT) ||
517 mStreams[i]->isTypeOf(CAM_STREAM_TYPE_POSTVIEW) ||
518 mStreams[i]->isOrignalTypeOf(CAM_STREAM_TYPE_POSTVIEW) ) ) {
519 cam_stream_parm_buffer_t param_buf;
520 memset(¶m_buf, 0, sizeof(cam_stream_parm_buffer_t));
521 param_buf.type = CAM_STREAM_PARAM_TYPE_SET_FLIP;
522 param_buf.flipInfo.flip_mask = param.getFlipMode(CAM_STREAM_TYPE_SNAPSHOT);
523 rc = mStreams[i]->setParameter(param_buf);
524 if (rc != NO_ERROR) {
525 ALOGE("%s: set snapshot stream flip failed", __func__);
526 }
527 }
528 }
529 }
530 return rc;
531 }
532
533 /*===========================================================================
534 * FUNCTION : QCameraPicChannel
535 *
536 * DESCRIPTION: constructor of QCameraPicChannel
537 *
538 * PARAMETERS :
539 * @cam_handle : camera handle
540 * @cam_ops : ptr to camera ops table
541 *
542 * RETURN : none
543 *==========================================================================*/
QCameraPicChannel(uint32_t cam_handle,mm_camera_ops_t * cam_ops)544 QCameraPicChannel::QCameraPicChannel(uint32_t cam_handle,
545 mm_camera_ops_t *cam_ops) :
546 QCameraChannel(cam_handle, cam_ops)
547 {
548 m_bAllowDynBufAlloc = true;
549 }
550
551 /*===========================================================================
552 * FUNCTION : QCameraPicChannel
553 *
554 * DESCRIPTION: default constructor of QCameraPicChannel
555 *
556 * PARAMETERS : none
557 *
558 * RETURN : none
559 *==========================================================================*/
QCameraPicChannel()560 QCameraPicChannel::QCameraPicChannel()
561 {
562 m_bAllowDynBufAlloc = true;
563 }
564
565 /*===========================================================================
566 * FUNCTION : ~QCameraPicChannel
567 *
568 * DESCRIPTION: destructor of QCameraPicChannel
569 *
570 * PARAMETERS : none
571 *
572 * RETURN : none
573 *==========================================================================*/
~QCameraPicChannel()574 QCameraPicChannel::~QCameraPicChannel()
575 {
576 }
577
578 /*===========================================================================
579 * FUNCTION : takePicture
580 *
581 * DESCRIPTION: send request for queued snapshot frames
582 *
583 * PARAMETERS :
584 * @num_of_snapshot : number of snapshot frames requested
585 * @num_of_retro_snapshot : number of retro snapshot frames requested
586 *
587 * RETURN : int32_t type of status
588 * NO_ERROR -- success
589 * none-zero failure code
590 *==========================================================================*/
takePicture(uint8_t num_of_snapshot,uint8_t num_of_retro_snapshot)591 int32_t QCameraPicChannel::takePicture (
592 uint8_t num_of_snapshot,
593 uint8_t num_of_retro_snapshot)
594 {
595 int32_t rc = m_camOps->request_super_buf(m_camHandle,
596 m_handle,
597 num_of_snapshot,
598 num_of_retro_snapshot);
599 return rc;
600 }
601
602 /*===========================================================================
603 * FUNCTION : cancelPicture
604 *
605 * DESCRIPTION: cancel request for queued snapshot frames
606 *
607 * PARAMETERS : none
608 *
609 * RETURN : int32_t type of status
610 * NO_ERROR -- success
611 * none-zero failure code
612 *==========================================================================*/
cancelPicture()613 int32_t QCameraPicChannel::cancelPicture()
614 {
615 int32_t rc = m_camOps->cancel_super_buf_request(m_camHandle, m_handle);
616 return rc;
617 }
618
619 /*===========================================================================
620 * FUNCTION : startAdvancedCapture
621 *
622 * DESCRIPTION: start advanced capture based on advanced capture type.
623 *
624 * PARAMETERS :
625 * @type : advanced capture type.
626 *
627 * RETURN : int32_t type of status
628 * NO_ERROR -- success
629 * none-zero failure code
630 *==========================================================================*/
startAdvancedCapture(mm_camera_advanced_capture_t type)631 int32_t QCameraPicChannel::startAdvancedCapture(mm_camera_advanced_capture_t type)
632 {
633 int32_t rc = m_camOps->process_advanced_capture(m_camHandle, type,
634 m_handle, 1);
635 return rc;
636 }
637
638 /*===========================================================================
639 * FUNCTION : QCameraVideoChannel
640 *
641 * DESCRIPTION: constructor of QCameraVideoChannel
642 *
643 * PARAMETERS :
644 * @cam_handle : camera handle
645 * @cam_ops : ptr to camera ops table
646 *
647 * RETURN : none
648 *==========================================================================*/
QCameraVideoChannel(uint32_t cam_handle,mm_camera_ops_t * cam_ops)649 QCameraVideoChannel::QCameraVideoChannel(uint32_t cam_handle,
650 mm_camera_ops_t *cam_ops) :
651 QCameraChannel(cam_handle, cam_ops)
652 {
653 }
654
655 /*===========================================================================
656 * FUNCTION : QCameraVideoChannel
657 *
658 * DESCRIPTION: default constructor of QCameraVideoChannel
659 *
660 * PARAMETERS : none
661 *
662 * RETURN : none
663 *==========================================================================*/
QCameraVideoChannel()664 QCameraVideoChannel::QCameraVideoChannel()
665 {
666 }
667
668 /*===========================================================================
669 * FUNCTION : ~QCameraVideoChannel
670 *
671 * DESCRIPTION: destructor of QCameraVideoChannel
672 *
673 * PARAMETERS : none
674 *
675 * RETURN : none
676 *==========================================================================*/
~QCameraVideoChannel()677 QCameraVideoChannel::~QCameraVideoChannel()
678 {
679 }
680
681 /*===========================================================================
682 * FUNCTION : releaseFrame
683 *
684 * DESCRIPTION: return video frame from app
685 *
686 * PARAMETERS :
687 * @opaque : ptr to video frame to be returned
688 * @isMetaData : if frame is a metadata or real frame
689 *
690 * RETURN : int32_t type of status
691 * NO_ERROR -- success
692 * none-zero failure code
693 *==========================================================================*/
releaseFrame(const void * opaque,bool isMetaData)694 int32_t QCameraVideoChannel::releaseFrame(const void * opaque, bool isMetaData)
695 {
696 QCameraStream *pVideoStream = NULL;
697 for (int i = 0; i < m_numStreams; i++) {
698 if (mStreams[i] != NULL && mStreams[i]->isTypeOf(CAM_STREAM_TYPE_VIDEO)) {
699 pVideoStream = mStreams[i];
700 break;
701 }
702 }
703
704 if (NULL == pVideoStream) {
705 ALOGE("%s: No video stream in the channel", __func__);
706 return BAD_VALUE;
707 }
708
709 int32_t rc = pVideoStream->bufDone(opaque, isMetaData);
710 return rc;
711 }
712
713 /*===========================================================================
714 * FUNCTION : QCameraReprocessChannel
715 *
716 * DESCRIPTION: constructor of QCameraReprocessChannel
717 *
718 * PARAMETERS :
719 * @cam_handle : camera handle
720 * @cam_ops : ptr to camera ops table
721 * @pp_mask : post-proccess feature mask
722 *
723 * RETURN : none
724 *==========================================================================*/
QCameraReprocessChannel(uint32_t cam_handle,mm_camera_ops_t * cam_ops)725 QCameraReprocessChannel::QCameraReprocessChannel(uint32_t cam_handle,
726 mm_camera_ops_t *cam_ops) :
727 QCameraChannel(cam_handle, cam_ops),
728 m_pSrcChannel(NULL)
729 {
730 memset(mSrcStreamHandles, 0, sizeof(mSrcStreamHandles));
731 }
732
733 /*===========================================================================
734 * FUNCTION : QCameraReprocessChannel
735 *
736 * DESCRIPTION: default constructor of QCameraReprocessChannel
737 *
738 * PARAMETERS : none
739 *
740 * RETURN : none
741 *==========================================================================*/
QCameraReprocessChannel()742 QCameraReprocessChannel::QCameraReprocessChannel() :
743 m_pSrcChannel(NULL)
744 {
745 }
746
747 /*===========================================================================
748 * FUNCTION : ~QCameraReprocessChannel
749 *
750 * DESCRIPTION: destructor of QCameraReprocessChannel
751 *
752 * PARAMETERS : none
753 *
754 * RETURN : none
755 *==========================================================================*/
~QCameraReprocessChannel()756 QCameraReprocessChannel::~QCameraReprocessChannel()
757 {
758 }
759
760 /*===========================================================================
761 * FUNCTION : addReprocStreamsFromSource
762 *
763 * DESCRIPTION: add reprocess streams from input source channel
764 *
765 * PARAMETERS :
766 * @allocator : stream related buffer allocator
767 * @config : pp feature configuration
768 * @pSrcChannel : ptr to input source channel that needs reprocess
769 * @minStreamBufNum: number of stream buffers needed
770 * @burstNum : number of burst captures needed
771 * @paddingInfo : padding information
772 * @param : reference to parameters
773 * @contStream : continous streaming mode or burst
774 * @offline : configure for offline reprocessing
775 *
776 * RETURN : int32_t type of status
777 * NO_ERROR -- success
778 * none-zero failure code
779 *==========================================================================*/
addReprocStreamsFromSource(QCameraAllocator & allocator,cam_pp_feature_config_t & config,QCameraChannel * pSrcChannel,uint8_t minStreamBufNum,uint32_t burstNum,cam_padding_info_t * paddingInfo,QCameraParameters & param,bool contStream,bool offline)780 int32_t QCameraReprocessChannel::addReprocStreamsFromSource(QCameraAllocator& allocator,
781 cam_pp_feature_config_t &config,
782 QCameraChannel *pSrcChannel,
783 uint8_t minStreamBufNum,
784 uint32_t burstNum,
785 cam_padding_info_t *paddingInfo,
786 QCameraParameters ¶m,
787 bool contStream,
788 bool offline)
789 {
790 int32_t rc = 0;
791 QCameraStream *pStream = NULL;
792 QCameraHeapMemory *pStreamInfoBuf = NULL;
793 cam_stream_info_t *streamInfo = NULL;
794
795 memset(mSrcStreamHandles, 0, sizeof(mSrcStreamHandles));
796
797 for (int i = 0; i < pSrcChannel->getNumOfStreams(); i++) {
798 pStream = pSrcChannel->getStreamByIndex(i);
799 if (pStream != NULL) {
800 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA) ||
801 pStream->isTypeOf(CAM_STREAM_TYPE_RAW)) {
802 // Skip metadata&raw for reprocess now because PP module cannot handle
803 // meta data&raw. May need furthur discussion if Imaginglib need meta data
804 continue;
805 }
806
807 if (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW) ||
808 pStream->isTypeOf(CAM_STREAM_TYPE_PREVIEW)) {
809 // Skip postview: in non zsl case, dont want to send
810 // thumbnail through reprocess.
811 // Skip preview: for same reason for zsl case
812 continue;
813 }
814
815 if(pStream->isTypeOf(CAM_STREAM_TYPE_PREVIEW) ||
816 pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW) ||
817 pStream->isOrignalTypeOf(CAM_STREAM_TYPE_PREVIEW) ||
818 pStream->isOrignalTypeOf(CAM_STREAM_TYPE_POSTVIEW)) {
819 uint32_t feature_mask = config.feature_mask;
820
821 if ((feature_mask & ~CAM_QCOM_FEATURE_HDR) == 0
822 && param.isHDREnabled()
823 && !param.isHDRThumbnailProcessNeeded()) {
824
825 // Skip thumbnail stream reprocessing in HDR
826 // if only hdr is enabled
827 continue;
828 }
829
830 // skip thumbnail reprocessing if not needed
831 if (!param.needThumbnailReprocess(&feature_mask)) {
832 continue;
833 }
834
835 //Don't do WNR for thumbnail
836 feature_mask &= ~CAM_QCOM_FEATURE_DENOISE2D;
837 if(!feature_mask) {
838 // Skip thumbnail stream reprocessing since no other
839 //reprocessing is enabled.
840 continue;
841 }
842 }
843
844 pStreamInfoBuf = allocator.allocateStreamInfoBuf(CAM_STREAM_TYPE_OFFLINE_PROC);
845 if (pStreamInfoBuf == NULL) {
846 ALOGE("%s: no mem for stream info buf", __func__);
847 rc = NO_MEMORY;
848 break;
849 }
850
851 streamInfo = (cam_stream_info_t *)pStreamInfoBuf->getPtr(0);
852 memset(streamInfo, 0, sizeof(cam_stream_info_t));
853 streamInfo->stream_type = CAM_STREAM_TYPE_OFFLINE_PROC;
854 rc = pStream->getFormat(streamInfo->fmt);
855 rc = pStream->getFrameDimension(streamInfo->dim);
856 if ( contStream ) {
857 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
858 streamInfo->num_of_burst = 0;
859 } else {
860 streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
861 streamInfo->num_of_burst = burstNum;
862 }
863
864 cam_stream_reproc_config_t rp_cfg;
865 memset(&rp_cfg, 0, sizeof(cam_stream_reproc_config_t));
866 if (offline) {
867 cam_frame_len_offset_t offset;
868 memset(&offset, 0, sizeof(cam_frame_len_offset_t));
869
870 rp_cfg.pp_type = CAM_OFFLINE_REPROCESS_TYPE;
871 pStream->getFormat(rp_cfg.offline.input_fmt);
872 pStream->getFrameDimension(rp_cfg.offline.input_dim);
873 pStream->getFrameOffset(offset);
874 rp_cfg.offline.input_buf_planes.plane_info = offset;
875 rp_cfg.offline.input_type = pStream->getMyType();
876 //For input metadata + input buffer
877 rp_cfg.offline.num_of_bufs = 2;
878 } else {
879 rp_cfg.pp_type = CAM_ONLINE_REPROCESS_TYPE;
880 rp_cfg.online.input_stream_id = pStream->getMyServerID();
881 rp_cfg.online.input_stream_type = pStream->getMyType();
882 }
883 streamInfo->reprocess_config = rp_cfg;
884 streamInfo->reprocess_config.pp_feature_config = config;
885
886 if (!(pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT) ||
887 pStream->isOrignalTypeOf(CAM_STREAM_TYPE_SNAPSHOT))) {
888 streamInfo->reprocess_config.pp_feature_config.feature_mask &= ~CAM_QCOM_FEATURE_CAC;
889 //Don't do WNR for thumbnail
890 streamInfo->reprocess_config.pp_feature_config.feature_mask &= ~CAM_QCOM_FEATURE_DENOISE2D;
891
892 if (param.isHDREnabled()
893 && !param.isHDRThumbnailProcessNeeded()){
894 streamInfo->reprocess_config.pp_feature_config.feature_mask
895 &= ~CAM_QCOM_FEATURE_HDR;
896 }
897 }
898
899 if (streamInfo->reprocess_config.pp_feature_config.feature_mask & CAM_QCOM_FEATURE_ROTATION) {
900 if (streamInfo->reprocess_config.pp_feature_config.rotation == ROTATE_90 ||
901 streamInfo->reprocess_config.pp_feature_config.rotation == ROTATE_270) {
902 // rotated by 90 or 270, need to switch width and height
903 int32_t temp = streamInfo->dim.height;
904 streamInfo->dim.height = streamInfo->dim.width;
905 streamInfo->dim.width = temp;
906 }
907 }
908
909 if (param.isZSLMode() &&
910 (streamInfo->reprocess_config.online.input_stream_type == CAM_STREAM_TYPE_SNAPSHOT)) {
911 // ZSL mode snapshot need reprocess to do the flip
912 int flipMode =
913 param.getFlipMode(streamInfo->reprocess_config.online.input_stream_type);
914 if (flipMode > 0) {
915 streamInfo->reprocess_config.pp_feature_config.feature_mask |= CAM_QCOM_FEATURE_FLIP;
916 streamInfo->reprocess_config.pp_feature_config.flip = flipMode;
917 }
918 }
919
920 if(streamInfo->reprocess_config.pp_feature_config.feature_mask & CAM_QCOM_FEATURE_SCALE){
921 //we only Scale Snapshot frame
922 if(pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT)){
923 //also check whether rotation is needed
924 if((streamInfo->reprocess_config.pp_feature_config.feature_mask & CAM_QCOM_FEATURE_ROTATION) &&
925 (streamInfo->reprocess_config.pp_feature_config.rotation == ROTATE_90 ||
926 streamInfo->reprocess_config.pp_feature_config.rotation == ROTATE_270)){
927 //need swap
928 streamInfo->dim.width = streamInfo->reprocess_config.pp_feature_config.scale_param.output_height;
929 streamInfo->dim.height = streamInfo->reprocess_config.pp_feature_config.scale_param.output_width;
930 }else{
931 streamInfo->dim.width = streamInfo->reprocess_config.pp_feature_config.scale_param.output_width;
932 streamInfo->dim.height = streamInfo->reprocess_config.pp_feature_config.scale_param.output_height;
933 }
934 }
935 CDBG_HIGH("%s: stream width=%d, height=%d.", __func__, streamInfo->dim.width, streamInfo->dim.height);
936 }
937
938 // save source stream handler
939 mSrcStreamHandles[m_numStreams] = pStream->getMyHandle();
940
941 // add reprocess stream
942 rc = addStream(allocator,
943 pStreamInfoBuf, minStreamBufNum,
944 paddingInfo,
945 NULL, NULL, false);
946 if (rc != NO_ERROR) {
947 ALOGE("%s: add reprocess stream failed, ret = %d", __func__, rc);
948 break;
949 }
950 }
951 }
952
953 if (rc == NO_ERROR) {
954 m_pSrcChannel = pSrcChannel;
955 }
956 return rc;
957 }
958
959 /*===========================================================================
960 * FUNCTION : getStreamBySrouceHandle
961 *
962 * DESCRIPTION: find reprocess stream by its source stream handle
963 *
964 * PARAMETERS :
965 * @srcHandle : source stream handle
966 *
967 * RETURN : ptr to reprocess stream if found. NULL if not found
968 *==========================================================================*/
getStreamBySrouceHandle(uint32_t srcHandle)969 QCameraStream * QCameraReprocessChannel::getStreamBySrouceHandle(uint32_t srcHandle)
970 {
971 QCameraStream *pStream = NULL;
972
973 for (int i = 0; i < m_numStreams; i++) {
974 if (mSrcStreamHandles[i] == srcHandle) {
975 pStream = mStreams[i];
976 break;
977 }
978 }
979
980 return pStream;
981 }
982
983 /*===========================================================================
984 * FUNCTION : stop
985 *
986 * DESCRIPTION: Unmap offline buffers and stop channel
987 *
988 * PARAMETERS : none
989 *
990 * RETURN : int32_t type of status
991 * NO_ERROR -- success
992 * none-zero failure code
993 *==========================================================================*/
stop()994 int32_t QCameraReprocessChannel::stop()
995 {
996 if (!mOfflineBuffers.empty()) {
997 QCameraStream *stream = NULL;
998 List<OfflineBuffer>::iterator it = mOfflineBuffers.begin();
999 int error = NO_ERROR;
1000 for( ; it != mOfflineBuffers.end(); it++) {
1001 stream = (*it).stream;
1002 if (NULL != stream) {
1003 error = stream->unmapBuf((*it).type,
1004 (*it).index,
1005 -1);
1006 if (NO_ERROR != error) {
1007 ALOGE("%s: Error during offline buffer unmap %d",
1008 __func__, error);
1009 }
1010 }
1011 }
1012 mOfflineBuffers.clear();
1013 }
1014
1015 return QCameraChannel::stop();
1016 }
1017
1018 /*===========================================================================
1019 * FUNCTION : doReprocessOffline
1020 *
1021 * DESCRIPTION: request to do offline reprocess on the frame
1022 *
1023 * PARAMETERS :
1024 * @frame : frame to be performed a reprocess
1025 *
1026 * RETURN : int32_t type of status
1027 * NO_ERROR -- success
1028 * none-zero failure code
1029 *==========================================================================*/
doReprocessOffline(mm_camera_super_buf_t * frame)1030 int32_t QCameraReprocessChannel::doReprocessOffline(
1031 mm_camera_super_buf_t *frame)
1032 {
1033 int32_t rc = 0;
1034 OfflineBuffer mappedBuffer;
1035
1036 if (m_numStreams < 1) {
1037 ALOGE("%s: No reprocess stream is created", __func__);
1038 return -1;
1039 }
1040 if (m_pSrcChannel == NULL) {
1041 ALOGE("%s: No source channel for reprocess", __func__);
1042 return -1;
1043 }
1044
1045 if (frame == NULL) {
1046 ALOGE("%s: Invalid source frame", __func__);
1047 return BAD_VALUE;
1048 }
1049
1050 // find meta data stream and index of meta data frame in the superbuf
1051 uint8_t meta_buf_index = -1;
1052 mm_camera_buf_def_t *meta_buf = NULL;
1053 QCameraStream *pStream = NULL;
1054 for (int i = 0; i < frame->num_bufs; i++) {
1055 pStream = m_pSrcChannel->getStreamByHandle(frame->bufs[i]->stream_id);
1056 if (pStream != NULL) {
1057 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) {
1058 meta_buf = frame->bufs[i];
1059 break;
1060 }
1061 }
1062 }
1063
1064 for (int i = 0; i < frame->num_bufs; i++) {
1065 pStream = getStreamBySrouceHandle(frame->bufs[i]->stream_id);
1066 if (pStream != NULL) {
1067 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) {
1068 continue;
1069 }
1070
1071 meta_buf_index = 0;
1072 if (NULL != meta_buf) {
1073 rc = pStream->mapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_META_BUF,
1074 meta_buf_index,
1075 -1,
1076 meta_buf->fd,
1077 meta_buf->frame_len);
1078 if (NO_ERROR != rc ) {
1079 ALOGE("%s : Error during metadata buffer mapping",
1080 __func__);
1081 break;
1082 }
1083 }
1084 mappedBuffer.index = meta_buf_index;
1085 mappedBuffer.stream = pStream;
1086 mappedBuffer.type = CAM_MAPPING_BUF_TYPE_OFFLINE_META_BUF;
1087 mOfflineBuffers.push_back(mappedBuffer);
1088
1089 int buf_index = 1;
1090 rc = pStream->mapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF,
1091 buf_index,
1092 -1,
1093 frame->bufs[i]->fd,
1094 frame->bufs[i]->frame_len);
1095 if (NO_ERROR != rc ) {
1096 ALOGE("%s : Error during reprocess input buffer mapping",
1097 __func__);
1098 break;
1099 }
1100 mappedBuffer.index = buf_index;
1101 mappedBuffer.stream = pStream;
1102 mappedBuffer.type = CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF;
1103 mOfflineBuffers.push_back(mappedBuffer);
1104
1105 cam_stream_parm_buffer_t param;
1106 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t));
1107 param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS;
1108 param.reprocess.buf_index = buf_index;
1109 param.reprocess.frame_pp_config.uv_upsample =
1110 frame->bufs[i]->is_uv_subsampled;
1111 if (NULL != meta_buf) {
1112 // we have meta data sent together with reprocess frame
1113 param.reprocess.meta_present = 1;
1114 param.reprocess.meta_buf_index = meta_buf_index;
1115 uint32_t stream_id = frame->bufs[i]->stream_id;
1116 QCameraStream *srcStream =
1117 m_pSrcChannel->getStreamByHandle(stream_id);
1118 metadata_buffer_t *pMetaData =
1119 (metadata_buffer_t *)meta_buf->buffer;
1120 if (NULL != pMetaData) {
1121 cam_crop_data_t *crop = NULL;
1122 if (IS_META_AVAILABLE(CAM_INTF_META_CROP_DATA, pMetaData)) {
1123 crop = (cam_crop_data_t *)
1124 POINTER_OF_META(CAM_INTF_META_CROP_DATA, pMetaData);
1125 }
1126
1127 if ((NULL != crop) && (NULL != srcStream)) {
1128 for (int j = 0; j < MAX_NUM_STREAMS; j++) {
1129 if (crop->crop_info[j].stream_id ==
1130 srcStream->getMyServerID()) {
1131 param.reprocess.frame_pp_config.crop.crop_enabled = 1;
1132 param.reprocess.frame_pp_config.crop.input_crop =
1133 crop->crop_info[j].crop;
1134 break;
1135 }
1136 }
1137 }
1138 }
1139 }
1140 rc = pStream->setParameter(param);
1141 if (rc != NO_ERROR) {
1142 ALOGE("%s: stream setParameter for reprocess failed",
1143 __func__);
1144 break;
1145 }
1146 }
1147 }
1148 return rc;
1149 }
1150
1151 /*===========================================================================
1152 * FUNCTION : doReprocess
1153 *
1154 * DESCRIPTION: request to do a reprocess on the frame
1155 *
1156 * PARAMETERS :
1157 * @frame : frame to be performed a reprocess
1158 *
1159 * RETURN : int32_t type of status
1160 * NO_ERROR -- success
1161 * none-zero failure code
1162 *==========================================================================*/
doReprocess(mm_camera_super_buf_t * frame)1163 int32_t QCameraReprocessChannel::doReprocess(mm_camera_super_buf_t *frame)
1164 {
1165 int32_t rc = 0;
1166 if (m_numStreams < 1) {
1167 ALOGE("%s: No reprocess stream is created", __func__);
1168 return -1;
1169 }
1170 if (m_pSrcChannel == NULL) {
1171 ALOGE("%s: No source channel for reprocess", __func__);
1172 return -1;
1173 }
1174
1175 // find meta data stream and index of meta data frame in the superbuf
1176 QCameraStream *pMetaStream = NULL;
1177 uint8_t meta_buf_index = 0;
1178 for (int i = 0; i < frame->num_bufs; i++) {
1179 QCameraStream *pStream = m_pSrcChannel->getStreamByHandle(frame->bufs[i]->stream_id);
1180 if (pStream != NULL) {
1181 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) {
1182 meta_buf_index = frame->bufs[i]->buf_idx;
1183 pMetaStream = pStream;
1184 break;
1185 }
1186 }
1187 }
1188
1189 for (int i = 0; i < frame->num_bufs; i++) {
1190 QCameraStream *pStream = getStreamBySrouceHandle(frame->bufs[i]->stream_id);
1191 if (pStream != NULL) {
1192 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) {
1193 // Skip metadata for reprocess now because PP module cannot handle meta data
1194 // May need furthur discussion if Imaginglib need meta data
1195 continue;
1196 }
1197
1198 if (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW) ||
1199 pStream->isTypeOf(CAM_STREAM_TYPE_PREVIEW)) {
1200 // Skip postview: In non zsl case, dont want to send
1201 // thumbnail through reprocess.
1202 // Skip preview: for same reason in ZSL case
1203 continue;
1204 }
1205
1206 cam_stream_parm_buffer_t param;
1207 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t));
1208 param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS;
1209 param.reprocess.buf_index = frame->bufs[i]->buf_idx;
1210 param.reprocess.frame_idx = frame->bufs[i]->frame_idx;
1211 param.reprocess.frame_pp_config.uv_upsample = frame->bufs[i]->is_uv_subsampled;
1212 if (pMetaStream != NULL) {
1213 // we have meta data frame bundled, sent together with reprocess frame
1214 param.reprocess.meta_present = 1;
1215 param.reprocess.meta_stream_handle = pMetaStream->getMyServerID();
1216 param.reprocess.meta_buf_index = meta_buf_index;
1217 }
1218 rc = pStream->setParameter(param);
1219 if (rc != NO_ERROR) {
1220 ALOGE("%s: stream setParameter for reprocess failed", __func__);
1221 break;
1222 }
1223 }
1224 }
1225 return rc;
1226 }
1227
1228 /*===========================================================================
1229 * FUNCTION : doReprocess
1230 *
1231 * DESCRIPTION: request to do a reprocess on the frame
1232 *
1233 * PARAMETERS :
1234 * @buf_fd : fd to the input buffer that needs reprocess
1235 * @buf_lenght : length of the input buffer
1236 * @ret_val : result of reprocess.
1237 * Example: Could be faceID in case of register face image.
1238 *
1239 * RETURN : int32_t type of status
1240 * NO_ERROR -- success
1241 * none-zero failure code
1242 *==========================================================================*/
doReprocess(int buf_fd,uint32_t buf_length,int32_t & ret_val)1243 int32_t QCameraReprocessChannel::doReprocess(int buf_fd,
1244 uint32_t buf_length,
1245 int32_t &ret_val)
1246 {
1247 int32_t rc = 0;
1248 if (m_numStreams < 1) {
1249 ALOGE("%s: No reprocess stream is created", __func__);
1250 return -1;
1251 }
1252
1253 uint32_t buf_idx = 0;
1254 for (int i = 0; i < m_numStreams; i++) {
1255 rc = mStreams[i]->mapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF,
1256 buf_idx, -1,
1257 buf_fd, buf_length);
1258
1259 if (rc == NO_ERROR) {
1260 cam_stream_parm_buffer_t param;
1261 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t));
1262 param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS;
1263 param.reprocess.buf_index = buf_idx;
1264 rc = mStreams[i]->setParameter(param);
1265 if (rc == NO_ERROR) {
1266 ret_val = param.reprocess.ret_val;
1267 }
1268 mStreams[i]->unmapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF,
1269 buf_idx, -1);
1270 }
1271 }
1272 return rc;
1273 }
1274
1275 }; // namespace qcamera
1276