1 /* Copyright (c) 2012-2016, The Linux Foundation. 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 // System dependencies
33 #include <utils/Errors.h>
34
35 // Camera dependencies
36 #include "QCamera2HWI.h"
37
38 extern "C" {
39 #include "mm_camera_dbg.h"
40 }
41
42 using namespace android;
43
44 namespace qcamera {
45
46 /*===========================================================================
47 * FUNCTION : QCameraChannel
48 *
49 * DESCRIPTION: constrcutor of QCameraChannel
50 *
51 * PARAMETERS :
52 * @cam_handle : camera handle
53 * @cam_ops : ptr to camera ops table
54 *
55 * RETURN : none
56 *==========================================================================*/
QCameraChannel(uint32_t cam_handle,mm_camera_ops_t * cam_ops)57 QCameraChannel::QCameraChannel(uint32_t cam_handle,
58 mm_camera_ops_t *cam_ops)
59 {
60 m_camHandle = cam_handle;
61 m_camOps = cam_ops;
62 m_bIsActive = false;
63 m_bAllowDynBufAlloc = false;
64 mDualChannel = is_dual_camera_by_handle(cam_handle);
65 m_handle = 0;
66 }
67
68 /*===========================================================================
69 * FUNCTION : QCameraChannel
70 *
71 * DESCRIPTION: default constrcutor of QCameraChannel
72 *
73 * PARAMETERS : none
74 *
75 * RETURN : none
76 *==========================================================================*/
QCameraChannel()77 QCameraChannel::QCameraChannel()
78 {
79 m_camHandle = 0;
80 m_camOps = NULL;
81 m_bIsActive = false;
82 mDualChannel = 0;
83 m_handle = 0;
84 }
85
86 /*===========================================================================
87 * FUNCTION : ~QCameraChannel
88 *
89 * DESCRIPTION: destructor of QCameraChannel
90 *
91 * PARAMETERS : none
92 *
93 * RETURN : none
94 *==========================================================================*/
~QCameraChannel()95 QCameraChannel::~QCameraChannel()
96 {
97 if (m_bIsActive) {
98 stop();
99 }
100 for (size_t i = 0; i < mStreams.size(); i++) {
101 if (mStreams[i] != NULL) {
102 if (validate_handle(m_handle, mStreams[i]->getChannelHandle())) {
103 delete mStreams[i];
104 }
105 }
106 }
107 mStreams.clear();
108 m_camOps->delete_channel(m_camHandle, m_handle);
109 m_handle = 0;
110 }
111
112 /*===========================================================================
113 * FUNCTION : deleteChannel
114 *
115 * DESCRIPTION: deletes a camera channel
116 *
117 * PARAMETERS : none
118 *
119 * RETURN : none
120 *==========================================================================*/
deleteChannel()121 void QCameraChannel::deleteChannel()
122 {
123 if (m_bIsActive) {
124 stop();
125 }
126 for (size_t i = 0; i < mStreams.size(); i++) {
127 if ((mStreams[i] != NULL) &&
128 (validate_handle(m_handle, mStreams[i]->getChannelHandle()))) {
129 mStreams[i]->deleteStream();
130 }
131 }
132 m_camOps->delete_channel(m_camHandle, m_handle);
133 }
134
135 /*===========================================================================
136 * FUNCTION : setStreamSyncCB
137 *
138 * DESCRIPTION: reg callback function to stream of stream type
139 *
140 * PARAMETERS :
141 * @stream_type : Stream type for which callback needs to be registered.
142 * @stream_cb : Callback function
143
144 * RETURN : int32_t type of status
145 * NO_ERROR -- success
146 * non-zero failure code
147 *==========================================================================*/
setStreamSyncCB(cam_stream_type_t stream_type,stream_cb_routine stream_cb)148 int32_t QCameraChannel::setStreamSyncCB (cam_stream_type_t stream_type,
149 stream_cb_routine stream_cb)
150 {
151 int32_t rc = UNKNOWN_ERROR;
152 for (size_t i = 0; i < mStreams.size(); i++) {
153 if ((mStreams[i] != NULL) && (stream_type == mStreams[i]->getMyType())) {
154 rc = mStreams[i]->setSyncDataCB(stream_cb);
155 break;
156 }
157 }
158 return rc;
159 }
160
161 /*===========================================================================
162 * FUNCTION : init
163 *
164 * DESCRIPTION: initialization of channel
165 *
166 * PARAMETERS :
167 * @attr : channel bundle attribute setting
168 * @dataCB : data notify callback
169 * @userData: user data ptr
170 *
171 * RETURN : int32_t type of status
172 * NO_ERROR -- success
173 * none-zero failure code
174 *==========================================================================*/
init(mm_camera_channel_attr_t * attr,mm_camera_buf_notify_t dataCB,void * userData)175 int32_t QCameraChannel::init(mm_camera_channel_attr_t *attr,
176 mm_camera_buf_notify_t dataCB,
177 void *userData)
178 {
179 m_handle = m_camOps->add_channel(m_camHandle,
180 attr,
181 dataCB,
182 userData);
183 if (m_handle == 0) {
184 LOGE("Add channel failed");
185 return UNKNOWN_ERROR;
186 }
187
188 mActiveCameras = MM_CAMERA_TYPE_MAIN;
189 if (isDualChannel()) {
190 mActiveCameras |= MM_CAMERA_TYPE_AUX;
191 }
192 mMasterCamera = MM_CAMERA_TYPE_MAIN;
193 mBundledSnapshot = false;
194 return NO_ERROR;
195 }
196
197 /*===========================================================================
198 * FUNCTION : getChHandleForStream
199 *
200 * DESCRIPTION: return actual channel handle based on use case per stream
201 *
202 * PARAMETERS :
203 * @ch_type : type of channel
204 *
205 * RETURN : number of buffers needed
206 * NOTE : Based on the use cases and auxillary camera type,
207 we can decide channel handle for streams.
208 Incase, we want to avoid any stream for auxillary camera,
209 we can decide here.
210 *==========================================================================*/
getChHandleForStream(cam_stream_type_t stream_type)211 uint32_t QCameraChannel::getChHandleForStream(cam_stream_type_t stream_type)
212 {
213 uint32_t handle = m_handle;
214 if (!mDualChannel) {
215 return m_handle;
216 }
217
218 /*Based on the use case, decide channel handle for channel*/
219 switch (stream_type) {
220 case CAM_STREAM_TYPE_PREVIEW:
221 case CAM_STREAM_TYPE_SNAPSHOT:
222 case CAM_STREAM_TYPE_VIDEO:
223 case CAM_STREAM_TYPE_METADATA:
224 case CAM_STREAM_TYPE_ANALYSIS:
225 case CAM_STREAM_TYPE_CALLBACK:
226 handle = m_handle;
227 break;
228 case CAM_STREAM_TYPE_POSTVIEW:
229 case CAM_STREAM_TYPE_RAW:
230 case CAM_STREAM_TYPE_OFFLINE_PROC:
231 case CAM_STREAM_TYPE_DEFAULT:
232 case CAM_STREAM_TYPE_MAX:
233 default:
234 handle = get_main_camera_handle(m_handle);
235 break;
236 }
237 return handle;
238 }
239
240 /*===========================================================================
241 * FUNCTION : addStream
242 *
243 * DESCRIPTION: add a stream into channel
244 *
245 * PARAMETERS :
246 * @allocator : stream related buffer allocator
247 * @streamInfoBuf : ptr to buf that contains stream info
248 * @miscBuf : ptr to buf that contains misc buffers
249 * @minStreamBufNum: number of stream buffers needed
250 * @paddingInfo : padding information
251 * @stream_cb : stream data notify callback
252 * @userdata : user data ptr
253 * @bDynAllocBuf : flag indicating if allow allocate buffers in 2 steps
254 * @online_rotation: rotation applied online
255 * @cam_type : Camera type in case of dual camera
256 *
257 * RETURN : int32_t type of status
258 * NO_ERROR -- success
259 * none-zero failure code
260 *==========================================================================*/
addStream(QCameraAllocator & allocator,QCameraHeapMemory * streamInfoBuf,QCameraHeapMemory * miscBuf,cam_padding_info_t * paddingInfo,stream_cb_routine stream_cb,void * userdata,bool bDynAllocBuf,bool bDeffAlloc,cam_rotation_t online_rotation,uint32_t cam_type)261 int32_t QCameraChannel::addStream(QCameraAllocator &allocator,
262 QCameraHeapMemory *streamInfoBuf, QCameraHeapMemory *miscBuf,
263 cam_padding_info_t *paddingInfo, stream_cb_routine stream_cb,
264 void *userdata, bool bDynAllocBuf, bool bDeffAlloc,
265 cam_rotation_t online_rotation,
266 uint32_t cam_type)
267 {
268 int32_t rc = NO_ERROR;
269 uint32_t ch_handle = m_handle;
270
271 if (mStreams.size() >= MAX_STREAM_NUM_IN_BUNDLE) {
272 LOGE("stream number (%zu) exceeds max limit (%d)",
273 mStreams.size(), MAX_STREAM_NUM_IN_BUNDLE);
274 if (streamInfoBuf != NULL) {
275 streamInfoBuf->deallocate();
276 delete streamInfoBuf;
277 streamInfoBuf = NULL;
278 }
279 return BAD_VALUE;
280 }
281
282 if (cam_type == MM_CAMERA_TYPE_MAIN) {
283 ch_handle = get_main_camera_handle(m_handle);
284 } else if (cam_type == MM_CAMERA_TYPE_AUX) {
285 ch_handle = get_aux_camera_handle(m_handle);
286 }
287
288 QCameraStream *pStream = new QCameraStream(allocator,
289 m_camHandle, ch_handle, m_camOps, paddingInfo, bDeffAlloc,
290 online_rotation);
291 if (pStream == NULL) {
292 LOGE("No mem for Stream");
293 if (streamInfoBuf != NULL) {
294 streamInfoBuf->deallocate();
295 delete streamInfoBuf;
296 streamInfoBuf = NULL;
297 }
298 return NO_MEMORY;
299 }
300
301 rc = pStream->init(streamInfoBuf, miscBuf,
302 stream_cb, userdata, bDynAllocBuf);
303 if (rc == 0) {
304 Mutex::Autolock lock(mStreamLock);
305 mStreams.add(pStream);
306 } else {
307 delete pStream;
308 }
309 return rc;
310 }
311
312 /*===========================================================================
313 * FUNCTION : linkStream
314 *
315 * DESCRIPTION: link a stream into channel
316 *
317 * PARAMETERS :
318 * @ch : Channel which the stream belongs to
319 * @stream : Stream which needs to be linked
320 *
321 * RETURN : int32_t type of status
322 * NO_ERROR -- success
323 * none-zero failure code
324 *==========================================================================*/
linkStream(QCameraChannel * ch,QCameraStream * stream)325 int32_t QCameraChannel::linkStream(QCameraChannel *ch, QCameraStream *stream)
326 {
327 int32_t rc = NO_ERROR;
328
329 if ((0 == m_handle) || (NULL == ch) || (NULL == stream)) {
330 return NO_INIT;
331 }
332
333 int32_t handle = m_camOps->link_stream(m_camHandle,
334 ch->getMyHandle(),
335 stream->getMyHandle(),
336 m_handle);
337 if (0 == handle) {
338 LOGE("Linking of stream failed");
339 rc = INVALID_OPERATION;
340 } else {
341 Mutex::Autolock lock(mStreamLock);
342 mStreams.add(stream);
343 }
344
345 return rc;
346 }
347
348 /*===========================================================================
349 * FUNCTION : start
350 *
351 * DESCRIPTION: start channel, which will start all streams belong to this channel
352 *
353 * PARAMETERS : None
354 *
355 * RETURN : int32_t type of status
356 * NO_ERROR -- success
357 * none-zero failure code
358 *==========================================================================*/
start()359 int32_t QCameraChannel::start()
360 {
361 int32_t rc = NO_ERROR;
362
363 if(m_bIsActive) {
364 LOGW("Attempt to start active channel");
365 return rc;
366 }
367
368 // there is more than one stream in the channel
369 // we need to notify mctl that all streams in this channel need to be bundled
370 for (size_t i = 0; i < mStreams.size(); i++) {
371 if ((mStreams[i] != NULL) &&
372 (validate_handle(m_handle, mStreams[i]->getChannelHandle()))) {
373 mStreams[i]->setBundleInfo();
374 }
375 }
376
377
378 for (size_t i = 0; i < mStreams.size(); i++) {
379 if ((mStreams[i] != NULL) &&
380 (validate_handle(m_handle, mStreams[i]->getChannelHandle()))) {
381 mStreams[i]->start();
382 }
383 }
384 rc = m_camOps->start_channel(m_camHandle, m_handle, /*start_sensor_streaming*/true);
385
386 if (rc != NO_ERROR) {
387 for (size_t i = 0; i < mStreams.size(); i++) {
388 if ((mStreams[i] != NULL) &&
389 (validate_handle(m_handle, mStreams[i]->getChannelHandle()))) {
390 mStreams[i]->stop();
391 }
392 }
393 } else {
394 m_bIsActive = true;
395 for (size_t i = 0; i < mStreams.size(); i++) {
396 if (mStreams[i] != NULL) {
397 mStreams[i]->cond_signal();
398 }
399 }
400 }
401
402 return rc;
403 }
404
405 /*===========================================================================
406 * FUNCTION : stop
407 *
408 * DESCRIPTION: stop a channel, which will stop all streams belong to this channel
409 *
410 * PARAMETERS : none
411 *
412 * RETURN : int32_t type of status
413 * NO_ERROR -- success
414 * none-zero failure code
415 *==========================================================================*/
stop()416 int32_t QCameraChannel::stop()
417 {
418 int32_t rc = NO_ERROR;
419 size_t i = 0;
420
421 if (!m_bIsActive) {
422 return NO_INIT;
423 }
424
425 {
426 Mutex::Autolock lock(mStreamLock);
427 while(i < mStreams.size()) {
428 if (mStreams[i] != NULL) {
429 if (validate_handle(m_handle, mStreams[i]->getChannelHandle())) {
430 mStreams[i]->stop();
431 i++;
432 } else {
433 // Remove linked stream from stream list
434 mStreams.removeAt(i);
435 }
436 }
437 }
438 }
439
440 rc = m_camOps->stop_channel(m_camHandle, m_handle, /*stop_immediately*/false);
441
442 m_bIsActive = false;
443 return rc;
444 }
445
446 /*===========================================================================
447 * FUNCTION : bufDone
448 *
449 * DESCRIPTION: return a stream buf back to kernel
450 *
451 * PARAMETERS :
452 * @recvd_frame : stream buf frame to be returned
453 *
454 * RETURN : int32_t type of status
455 * NO_ERROR -- success
456 * none-zero failure code
457 *==========================================================================*/
bufDone(mm_camera_super_buf_t * recvd_frame)458 int32_t QCameraChannel::bufDone(mm_camera_super_buf_t *recvd_frame)
459 {
460 int32_t rc = NO_ERROR;
461 for (uint32_t i = 0; i < recvd_frame->num_bufs; i++) {
462 if (recvd_frame->bufs[i] != NULL) {
463 for (uint32_t j = 0; j < mStreams.size(); j++) {
464 if (mStreams[j] != NULL &&
465 (validate_handle(mStreams[j]->getMyHandle(),
466 recvd_frame->bufs[i]->stream_id))) {
467 rc = mStreams[j]->bufDone(recvd_frame->bufs[i]->buf_idx);
468 break; // break loop j
469 }
470 }
471 }
472 }
473
474 return rc;
475 }
476
477 /*===========================================================================
478 * FUNCTION : bufDone
479 *
480 * DESCRIPTION: return specified buffer from super buffer to kernel
481 *
482 * PARAMETERS :
483 * @recvd_frame : stream buf frame to be returned
484 * @stream_id : stream ID of the buffer to be released
485 *
486 * RETURN : int32_t type of status
487 * NO_ERROR -- success
488 * none-zero failure code
489 *==========================================================================*/
bufDone(mm_camera_super_buf_t * recvd_frame,uint32_t stream_id)490 int32_t QCameraChannel::bufDone(mm_camera_super_buf_t *recvd_frame, uint32_t stream_id)
491 {
492 int32_t rc = NO_ERROR;
493 int32_t index;
494 for (int32_t i = 0; i < (int32_t)recvd_frame->num_bufs; i++) {
495 index = -1;
496 if ((recvd_frame->bufs[i] != NULL) &&
497 (recvd_frame->bufs[i]->stream_id == stream_id)) {
498 for (uint32_t j = 0; j < mStreams.size(); j++) {
499 if ((mStreams[j] != NULL) &&
500 (validate_handle(mStreams[j]->getMyHandle(),
501 recvd_frame->bufs[i]->stream_id))) {
502 rc = mStreams[j]->bufDone(recvd_frame->bufs[i]->buf_idx);
503 index = i;
504 break; // break loop j
505 }
506 }
507 if ((index >= 0) && (index < (int32_t)recvd_frame->num_bufs)) {
508 for (int32_t j = index; j < (int32_t)(recvd_frame->num_bufs - 1); j++) {
509 recvd_frame->bufs[j] = recvd_frame->bufs[j + 1];
510 }
511 recvd_frame->num_bufs--;
512 i--;
513 }
514 }
515 }
516
517 return rc;
518 }
519
520 /*===========================================================================
521 * FUNCTION : processZoomDone
522 *
523 * DESCRIPTION: process zoom done event
524 *
525 * PARAMETERS :
526 * @previewWindoe : ptr to preview window ops table, needed to set preview
527 * crop information
528 * @crop_info : crop info as a result of zoom operation
529 *
530 * RETURN : int32_t type of status
531 * NO_ERROR -- success
532 * none-zero failure code
533 *==========================================================================*/
processZoomDone(preview_stream_ops_t * previewWindow,cam_crop_data_t & crop_info)534 int32_t QCameraChannel::processZoomDone(preview_stream_ops_t *previewWindow,
535 cam_crop_data_t &crop_info)
536 {
537 int32_t rc = NO_ERROR;
538 Mutex::Autolock lock(mStreamLock);
539 for (size_t i = 0; i < mStreams.size(); i++) {
540 if ((mStreams[i] != NULL) &&
541 (validate_handle(m_handle, mStreams[i]->getChannelHandle()))) {
542 rc = mStreams[i]->processZoomDone(previewWindow, crop_info);
543 }
544 }
545 return rc;
546 }
547
548 /*===========================================================================
549 * FUNCTION : getStreamByHandle
550 *
551 * DESCRIPTION: return stream object by stream handle
552 *
553 * PARAMETERS :
554 * @streamHandle : stream handle
555 *
556 * RETURN : stream object. NULL if not found
557 *==========================================================================*/
getStreamByHandle(uint32_t streamHandle)558 QCameraStream *QCameraChannel::getStreamByHandle(uint32_t streamHandle)
559 {
560 for (size_t i = 0; i < mStreams.size(); i++) {
561 if (mStreams[i] != NULL &&
562 (validate_handle(mStreams[i]->getMyHandle(), streamHandle))) {
563 return mStreams[i];
564 }
565 }
566 return NULL;
567 }
568
569 /*===========================================================================
570 * FUNCTION : getStreamByServerID
571 *
572 * DESCRIPTION: return stream object by stream server ID from daemon
573 *
574 * PARAMETERS :
575 * @serverID : stream server ID
576 *
577 * RETURN : stream object. NULL if not found
578 *==========================================================================*/
getStreamByServerID(uint32_t serverID)579 QCameraStream *QCameraChannel::getStreamByServerID(uint32_t serverID)
580 {
581 for (size_t i = 0; i < mStreams.size(); i++) {
582 if (mStreams[i] != NULL && mStreams[i]->getMyServerID() == serverID) {
583 return mStreams[i];
584 }
585 }
586 return NULL;
587 }
588
589 /*===========================================================================
590 * FUNCTION : getStreamByIndex
591 *
592 * DESCRIPTION: return stream object by index of streams in the channel
593 *
594 * PARAMETERS :
595 * @index : index of stream in the channel
596 *
597 * RETURN : stream object. NULL if not found
598 *==========================================================================*/
getStreamByIndex(uint32_t index)599 QCameraStream *QCameraChannel::getStreamByIndex(uint32_t index)
600 {
601 if (index >= MAX_STREAM_NUM_IN_BUNDLE) {
602 return NULL;
603 }
604
605 if (index < mStreams.size()) {
606 return mStreams[index];
607 }
608 return NULL;
609 }
610
611 /*===========================================================================
612 * FUNCTION : UpdateStreamBasedParameters
613 *
614 * DESCRIPTION: update any stream based settings from parameters
615 *
616 * PARAMETERS :
617 * @param : reference to parameters object
618 *
619 * RETURN : int32_t type of status
620 * NO_ERROR -- success
621 * none-zero failure code
622 *==========================================================================*/
UpdateStreamBasedParameters(QCameraParametersIntf & param)623 int32_t QCameraChannel::UpdateStreamBasedParameters(QCameraParametersIntf ¶m)
624 {
625 int32_t rc = NO_ERROR;
626 Mutex::Autolock lock(mStreamLock);
627 if (param.isPreviewFlipChanged()) {
628 // try to find preview stream
629 for (size_t i = 0; i < mStreams.size(); i++) {
630 if ((mStreams[i] != NULL) &&
631 (validate_handle(m_handle, mStreams[i]->getChannelHandle())) &&
632 (mStreams[i]->isTypeOf(CAM_STREAM_TYPE_PREVIEW) ||
633 (mStreams[i]->isOrignalTypeOf(CAM_STREAM_TYPE_PREVIEW))) ) {
634 cam_stream_parm_buffer_t param_buf;
635 memset(¶m_buf, 0, sizeof(cam_stream_parm_buffer_t));
636 param_buf.type = CAM_STREAM_PARAM_TYPE_SET_FLIP;
637 param_buf.flipInfo.flip_mask =
638 (uint32_t)param.getFlipMode(CAM_STREAM_TYPE_PREVIEW);
639 rc = mStreams[i]->setParameter(param_buf);
640 if (rc != NO_ERROR) {
641 LOGW("set preview stream flip failed");
642 }
643 }
644 }
645 }
646 if (param.isVideoFlipChanged()) {
647 // try to find video stream
648 for (size_t i = 0; i < mStreams.size(); i++) {
649 if ((mStreams[i] != NULL) &&
650 (validate_handle(m_handle, mStreams[i]->getChannelHandle())) &&
651 (mStreams[i]->isTypeOf(CAM_STREAM_TYPE_VIDEO) ||
652 (mStreams[i]->isOrignalTypeOf(CAM_STREAM_TYPE_VIDEO))) ) {
653 cam_stream_parm_buffer_t param_buf;
654 memset(¶m_buf, 0, sizeof(cam_stream_parm_buffer_t));
655 param_buf.type = CAM_STREAM_PARAM_TYPE_SET_FLIP;
656 param_buf.flipInfo.flip_mask =
657 (uint32_t)param.getFlipMode(CAM_STREAM_TYPE_VIDEO);
658 rc = mStreams[i]->setParameter(param_buf);
659 if (rc != NO_ERROR) {
660 LOGW("set video stream flip failed");
661 }
662 }
663 }
664 }
665 if (param.isSnapshotFlipChanged()) {
666 // try to find snapshot/postview stream
667 for (size_t i = 0; i < mStreams.size(); i++) {
668 if (mStreams[i] != NULL &&
669 (validate_handle(m_handle, mStreams[i]->getChannelHandle())) &&
670 (mStreams[i]->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT) ||
671 mStreams[i]->isOrignalTypeOf(CAM_STREAM_TYPE_SNAPSHOT) ||
672 mStreams[i]->isTypeOf(CAM_STREAM_TYPE_POSTVIEW) ||
673 mStreams[i]->isOrignalTypeOf(CAM_STREAM_TYPE_POSTVIEW) ) ) {
674 cam_stream_parm_buffer_t param_buf;
675 memset(¶m_buf, 0, sizeof(cam_stream_parm_buffer_t));
676 param_buf.type = CAM_STREAM_PARAM_TYPE_SET_FLIP;
677 param_buf.flipInfo.flip_mask =
678 (uint32_t)param.getFlipMode(CAM_STREAM_TYPE_SNAPSHOT);
679 rc = mStreams[i]->setParameter(param_buf);
680 if (rc != NO_ERROR) {
681 LOGW("set snapshot stream flip failed");
682 }
683 }
684 }
685 }
686 return rc;
687 }
688
689 /*===========================================================================
690 * FUNCTION : processCameraControl
691 *
692 * DESCRIPTION: Suspend and resume camera
693 *
694 * PARAMETERS :
695 * @camState : Camera start. MAIN/AUX/MAIN&AUX
696 *
697 * RETURN : int32_t type of status
698 * NO_ERROR -- success
699 * none-zero failure code
700 *==========================================================================*/
processCameraControl(uint32_t camState,bool bundledSnapshot)701 int32_t QCameraChannel::processCameraControl(
702 uint32_t camState,
703 bool bundledSnapshot)
704 {
705 int32_t ret = NO_ERROR;
706
707 for (size_t i = 0; i < mStreams.size(); i++) {
708 if (mStreams[i] != NULL && mStreams[i]->isDualStream()) {
709 ret = mStreams[i]->processCameraControl(camState);
710 if (ret != NO_ERROR) {
711 LOGE("Stream handle failed");
712 break;
713 }
714 }
715 }
716
717 mActiveCameras = camState;
718 mBundledSnapshot = bundledSnapshot;
719 return ret;
720 }
721
722 /*===========================================================================
723 * FUNCTION : switchChannelCb
724 *
725 * DESCRIPTION: switch channel's in case of dual camera
726 *
727 * PARAMETERS :
728 * @camMaster : Master camera
729 *
730 * RETURN : int32_t type of status
731 * NO_ERROR -- success
732 * none-zero failure code
733 *==========================================================================*/
switchChannelCb(uint32_t camMaster)734 int32_t QCameraChannel::switchChannelCb(uint32_t camMaster)
735 {
736 int32_t ret = NO_ERROR;
737
738 for (size_t i = 0; i < mStreams.size(); i++) {
739 if (mStreams[i] != NULL && mStreams[i]->isDualStream()) {
740 ret = mStreams[i]->switchStreamCb(camMaster);
741 if (ret != NO_ERROR) {
742 LOGE("Stream Switch Failed");
743 break;
744 }
745 }
746 }
747
748 // Update master camera
749 mMasterCamera = camMaster;
750 return ret;
751 }
752
753 /*===========================================================================
754 * FUNCTION : getSnapshotHandle
755 *
756 * DESCRIPTION: Get the camera handle for snapshot based on the bundlesnapshot
757 * flag and active camera state
758 *
759 * PARAMETERS : None
760 *
761 * RETURN : camera handle for snapshot
762 *
763 *==========================================================================*/
getSnapshotHandle()764 uint32_t QCameraChannel::getSnapshotHandle()
765 {
766 uint32_t snapshotHandle = 0;
767
768 if ((mActiveCameras == MM_CAMERA_DUAL_CAM) && mBundledSnapshot) {
769 snapshotHandle = m_handle;
770 } else {
771 snapshotHandle = (mMasterCamera == MM_CAMERA_TYPE_MAIN) ?
772 get_main_camera_handle(m_handle) : get_aux_camera_handle(m_handle);
773 }
774
775 return snapshotHandle;
776 }
777
778 /*===========================================================================
779 * FUNCTION : QCameraPicChannel
780 *
781 * DESCRIPTION: constructor of QCameraPicChannel
782 *
783 * PARAMETERS :
784 * @cam_handle : camera handle
785 * @cam_ops : ptr to camera ops table
786 *
787 * RETURN : none
788 *==========================================================================*/
QCameraPicChannel(uint32_t cam_handle,mm_camera_ops_t * cam_ops)789 QCameraPicChannel::QCameraPicChannel(uint32_t cam_handle,
790 mm_camera_ops_t *cam_ops) :
791 QCameraChannel(cam_handle, cam_ops)
792 {
793 m_bAllowDynBufAlloc = true;
794 }
795
796 /*===========================================================================
797 * FUNCTION : QCameraPicChannel
798 *
799 * DESCRIPTION: default constructor of QCameraPicChannel
800 *
801 * PARAMETERS : none
802 *
803 * RETURN : none
804 *==========================================================================*/
QCameraPicChannel()805 QCameraPicChannel::QCameraPicChannel()
806 {
807 m_bAllowDynBufAlloc = true;
808 }
809
810 /*===========================================================================
811 * FUNCTION : ~QCameraPicChannel
812 *
813 * DESCRIPTION: destructor of QCameraPicChannel
814 *
815 * PARAMETERS : none
816 *
817 * RETURN : none
818 *==========================================================================*/
~QCameraPicChannel()819 QCameraPicChannel::~QCameraPicChannel()
820 {
821 }
822
823 /*===========================================================================
824 * FUNCTION : takePicture
825 *
826 * DESCRIPTION: send request for queued snapshot frames
827 *
828 * PARAMETERS :
829 * @buf : request buf info
830 *
831 * RETURN : int32_t type of status
832 * NO_ERROR -- success
833 * none-zero failure code
834 *==========================================================================*/
takePicture(mm_camera_req_buf_t * buf)835 int32_t QCameraPicChannel::takePicture (mm_camera_req_buf_t *buf)
836 {
837 uint32_t snapshotHandle = getSnapshotHandle();
838 LOGD("mSnapshotHandle = 0x%x", snapshotHandle);
839 int32_t rc = m_camOps->request_super_buf(m_camHandle, snapshotHandle, buf);
840 return rc;
841 }
842
843 /*===========================================================================
844 * FUNCTION : cancelPicture
845 *
846 * DESCRIPTION: cancel request for queued snapshot frames
847 *
848 * PARAMETERS : none
849 *
850 * RETURN : int32_t type of status
851 * NO_ERROR -- success
852 * none-zero failure code
853 *==========================================================================*/
cancelPicture()854 int32_t QCameraPicChannel::cancelPicture()
855 {
856 int32_t rc = m_camOps->cancel_super_buf_request(m_camHandle, m_handle);
857 return rc;
858 }
859
860 /*===========================================================================
861 * FUNCTION : stopAdvancedCapture
862 *
863 * DESCRIPTION: stop advanced capture based on advanced capture type.
864 *
865 * PARAMETERS :
866 * @type : advanced capture type.
867 *
868 * RETURN : int32_t type of status
869 * NO_ERROR -- success
870 * none-zero failure code
871 *==========================================================================*/
stopAdvancedCapture(mm_camera_advanced_capture_t type)872 int32_t QCameraPicChannel::stopAdvancedCapture(mm_camera_advanced_capture_t type)
873 {
874 int32_t rc = m_camOps->process_advanced_capture(m_camHandle,
875 m_handle, type, 0, NULL);
876 return rc;
877 }
878
879 /*===========================================================================
880 * FUNCTION : startAdvancedCapture
881 *
882 * DESCRIPTION: start advanced capture based on advanced capture type.
883 *
884 * PARAMETERS :
885 * @type : advanced capture type.
886 * @config: advance capture config
887 *
888 * RETURN : int32_t type of status
889 * NO_ERROR -- success
890 * none-zero failure code
891 *==========================================================================*/
startAdvancedCapture(mm_camera_advanced_capture_t type,cam_capture_frame_config_t * config)892 int32_t QCameraPicChannel::startAdvancedCapture(mm_camera_advanced_capture_t type,
893 cam_capture_frame_config_t *config)
894 {
895 int32_t rc = NO_ERROR;
896
897 rc = m_camOps->process_advanced_capture(m_camHandle, getSnapshotHandle(), type,
898 1, config);
899 return rc;
900 }
901
902 /*===========================================================================
903 * FUNCTION : flushSuperbuffer
904 *
905 * DESCRIPTION: flush the all superbuffer frames.
906 *
907 * PARAMETERS :
908 * @frame_idx : frame index of focused frame
909 *
910 * RETURN : int32_t type of status
911 * NO_ERROR -- success
912 * none-zero failure code
913 *==========================================================================*/
flushSuperbuffer(uint32_t frame_idx)914 int32_t QCameraPicChannel::flushSuperbuffer(uint32_t frame_idx)
915 {
916 int32_t rc = m_camOps->flush_super_buf_queue(m_camHandle, m_handle, frame_idx);
917 return rc;
918 }
919
920 /*===========================================================================
921 * FUNCTION : QCameraVideoChannel
922 *
923 * DESCRIPTION: constructor of QCameraVideoChannel
924 *
925 * PARAMETERS :
926 * @cam_handle : camera handle
927 * @cam_ops : ptr to camera ops table
928 *
929 * RETURN : none
930 *==========================================================================*/
QCameraVideoChannel(uint32_t cam_handle,mm_camera_ops_t * cam_ops)931 QCameraVideoChannel::QCameraVideoChannel(uint32_t cam_handle,
932 mm_camera_ops_t *cam_ops) :
933 QCameraChannel(cam_handle, cam_ops)
934 {
935 }
936
937 /*===========================================================================
938 * FUNCTION : QCameraVideoChannel
939 *
940 * DESCRIPTION: default constructor of QCameraVideoChannel
941 *
942 * PARAMETERS : none
943 *
944 * RETURN : none
945 *==========================================================================*/
QCameraVideoChannel()946 QCameraVideoChannel::QCameraVideoChannel()
947 {
948 }
949
950 /*===========================================================================
951 * FUNCTION : ~QCameraVideoChannel
952 *
953 * DESCRIPTION: destructor of QCameraVideoChannel
954 *
955 * PARAMETERS : none
956 *
957 * RETURN : none
958 *==========================================================================*/
~QCameraVideoChannel()959 QCameraVideoChannel::~QCameraVideoChannel()
960 {
961 }
962
963 /*===========================================================================
964 * FUNCTION : takePicture
965 *
966 * DESCRIPTION: send request for queued snapshot frames
967 *
968 * PARAMETERS :
969 * @mm_camera_req_buf_t : request buf info
970 *
971 * RETURN : int32_t type of status
972 * NO_ERROR -- success
973 * none-zero failure code
974 *==========================================================================*/
takePicture(mm_camera_req_buf_t * buf)975 int32_t QCameraVideoChannel::takePicture(mm_camera_req_buf_t *buf)
976 {
977 uint32_t snapshotHandle = getSnapshotHandle();
978 LOGD("mSnapshotHandle = 0x%x", snapshotHandle);
979 int32_t rc = m_camOps->request_super_buf(m_camHandle, snapshotHandle, buf);
980 return rc;
981 }
982
983 /*===========================================================================
984 * FUNCTION : cancelPicture
985 *
986 * DESCRIPTION: cancel request for queued snapshot frames
987 *
988 * PARAMETERS : none
989 *
990 * RETURN : int32_t type of status
991 * NO_ERROR -- success
992 * none-zero failure code
993 *==========================================================================*/
cancelPicture()994 int32_t QCameraVideoChannel::cancelPicture()
995 {
996 int32_t rc = m_camOps->cancel_super_buf_request(m_camHandle, m_handle);
997 return rc;
998 }
999
1000 /*===========================================================================
1001 * FUNCTION : releaseFrame
1002 *
1003 * DESCRIPTION: return video frame from app
1004 *
1005 * PARAMETERS :
1006 * @opaque : ptr to video frame to be returned
1007 * @isMetaData : if frame is a metadata or real frame
1008 *
1009 * RETURN : int32_t type of status
1010 * NO_ERROR -- success
1011 * none-zero failure code
1012 *==========================================================================*/
releaseFrame(const void * opaque,bool isMetaData)1013 int32_t QCameraVideoChannel::releaseFrame(const void * opaque, bool isMetaData)
1014 {
1015 QCameraStream *pVideoStream = NULL;
1016 for (size_t i = 0; i < mStreams.size(); i++) {
1017 if (mStreams[i] != NULL && mStreams[i]->isTypeOf(CAM_STREAM_TYPE_VIDEO)) {
1018 pVideoStream = mStreams[i];
1019 break;
1020 }
1021 }
1022
1023 if (NULL == pVideoStream) {
1024 LOGE("No video stream in the channel");
1025 return BAD_VALUE;
1026 }
1027
1028 int32_t rc = pVideoStream->bufDone(opaque, isMetaData);
1029 return rc;
1030 }
1031
1032 /*===========================================================================
1033 * FUNCTION : QCameraReprocessChannel
1034 *
1035 * DESCRIPTION: constructor of QCameraReprocessChannel
1036 *
1037 * PARAMETERS :
1038 * @cam_handle : camera handle
1039 * @cam_ops : ptr to camera ops table
1040 *
1041 * RETURN : none
1042 *==========================================================================*/
QCameraReprocessChannel(uint32_t cam_handle,mm_camera_ops_t * cam_ops)1043 QCameraReprocessChannel::QCameraReprocessChannel(uint32_t cam_handle,
1044 mm_camera_ops_t *cam_ops) :
1045 QCameraChannel(cam_handle, cam_ops),
1046 m_pSrcChannel(NULL),
1047 mPassCount(0)
1048 {
1049 memset(mSrcStreamHandles, 0, sizeof(mSrcStreamHandles));
1050 }
1051
1052 /*===========================================================================
1053 * FUNCTION : QCameraReprocessChannel
1054 *
1055 * DESCRIPTION: default constructor of QCameraReprocessChannel
1056 *
1057 * PARAMETERS : none
1058 *
1059 * RETURN : none
1060 *==========================================================================*/
QCameraReprocessChannel()1061 QCameraReprocessChannel::QCameraReprocessChannel() :
1062 m_pSrcChannel(NULL),
1063 mPassCount(0)
1064 {
1065 }
1066
1067 /*===========================================================================
1068 * FUNCTION : ~QCameraReprocessChannel
1069 *
1070 * DESCRIPTION: destructor of QCameraReprocessChannel
1071 *
1072 * PARAMETERS : none
1073 *
1074 * RETURN : none
1075 *==========================================================================*/
~QCameraReprocessChannel()1076 QCameraReprocessChannel::~QCameraReprocessChannel()
1077 {
1078 }
1079
1080 /*===========================================================================
1081 * FUNCTION : addReprocStreamsFromSource
1082 *
1083 * DESCRIPTION: add reprocess streams from input source channel
1084 *
1085 * PARAMETERS :
1086 * @allocator : stream related buffer allocator
1087 * @featureConfig : pp feature configuration
1088 * @pSrcChannel : ptr to input source channel that needs reprocess
1089 * @minStreamBufNum: number of stream buffers needed
1090 * @burstNum : number of burst captures needed
1091 * @paddingInfo : padding information
1092 * @param : reference to parameters
1093 * @contStream : continous streaming mode or burst
1094 * @offline : configure for offline reprocessing
1095 *
1096 * RETURN : int32_t type of status
1097 * NO_ERROR -- success
1098 * none-zero failure code
1099 *==========================================================================*/
addReprocStreamsFromSource(QCameraAllocator & allocator,cam_pp_feature_config_t & featureConfig,QCameraChannel * pSrcChannel,uint8_t minStreamBufNum,uint8_t burstNum,cam_padding_info_t * paddingInfo,QCameraParametersIntf & param,bool contStream,bool offline)1100 int32_t QCameraReprocessChannel::addReprocStreamsFromSource(
1101 QCameraAllocator& allocator, cam_pp_feature_config_t &featureConfig,
1102 QCameraChannel *pSrcChannel, uint8_t minStreamBufNum, uint8_t burstNum,
1103 cam_padding_info_t *paddingInfo, QCameraParametersIntf ¶m, bool contStream,
1104 bool offline)
1105 {
1106 int32_t rc = 0;
1107 QCameraStream *pStream = NULL;
1108 QCameraHeapMemory *pStreamInfoBuf = NULL;
1109 QCameraHeapMemory *pMiscBuf = NULL;
1110 cam_stream_info_t *streamInfo = NULL;
1111 cam_padding_info_t padding;
1112
1113 memset(mSrcStreamHandles, 0, sizeof(mSrcStreamHandles));
1114 if (NULL == paddingInfo) {
1115 return BAD_VALUE;
1116 }
1117 padding = *paddingInfo;
1118 //Use maximum padding so that the buffer
1119 //can be rotated
1120 padding.width_padding = MAX(padding.width_padding, padding.height_padding);
1121 padding.height_padding = padding.width_padding;
1122 padding.offset_info.offset_x = 0;
1123 padding.offset_info.offset_y = 0;
1124
1125 LOGD("num of src stream = %d", pSrcChannel->getNumOfStreams());
1126 for (uint32_t i = 0; i < pSrcChannel->getNumOfStreams(); i++) {
1127 cam_pp_feature_config_t pp_featuremask = featureConfig;
1128 pStream = pSrcChannel->getStreamByIndex(i);
1129 if (pStream != NULL) {
1130 if (param.getofflineRAW() && !((pStream->isTypeOf(CAM_STREAM_TYPE_RAW))
1131 || (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW))
1132 || (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA))
1133 || (pStream->isOrignalTypeOf(CAM_STREAM_TYPE_RAW))
1134 || (pStream->isOrignalTypeOf(CAM_STREAM_TYPE_METADATA)))) {
1135 //Skip all the stream other than RAW and POSTVIEW incase of offline of RAW
1136 continue;
1137 }
1138
1139 if (pStream->isTypeOf(CAM_STREAM_TYPE_RAW)
1140 && (!param.getofflineRAW())) {
1141 // Skip raw for reprocess now because PP module cannot handle
1142 // meta data&raw. May need furthur discussion if Imaginglib need meta data
1143 continue;
1144 }
1145
1146 if (((pStream->isTypeOf(CAM_STREAM_TYPE_METADATA))
1147 && !((param.getManualCaptureMode() >=
1148 CAM_MANUAL_CAPTURE_TYPE_3) || (param.getQuadraCfa())))
1149 || (pStream->isTypeOf(CAM_STREAM_TYPE_ANALYSIS))) {
1150 // Skip metadata, if not manual capture or quadra cfa
1151 continue;
1152 }
1153
1154 if (pStream->isTypeOf(CAM_STREAM_TYPE_PREVIEW) ||
1155 pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW) ||
1156 pStream->isOrignalTypeOf(CAM_STREAM_TYPE_PREVIEW) ||
1157 pStream->isOrignalTypeOf(CAM_STREAM_TYPE_POSTVIEW)) {
1158 cam_feature_mask_t feature_mask = featureConfig.feature_mask;
1159
1160 // skip thumbnail reprocessing if not needed
1161 if (!param.needThumbnailReprocess(&feature_mask)) {
1162 continue;
1163 }
1164 // CAC, SHARPNESS, FLIP and WNR would have been already applied -
1165 // on preview/postview stream in realtime.
1166 // So, need not apply again.
1167 feature_mask &= ~(CAM_QCOM_FEATURE_DENOISE2D |
1168 CAM_QCOM_FEATURE_CAC |
1169 CAM_QCOM_FEATURE_SHARPNESS |
1170 CAM_QCOM_FEATURE_FLIP |
1171 CAM_QCOM_FEATURE_RAW_PROCESSING);
1172 if (!feature_mask) {
1173 // Skip thumbnail stream reprocessing since no other
1174 //reprocessing is enabled.
1175 continue;
1176 }
1177 }
1178
1179 // For quadra CFA, assign metada_bypass for first pass feature mask.
1180 // For second pass in quadra CFA mode, assign metadata_processing.
1181 // For normal reprocess(no quadra CFA), assign metadata_processing.
1182 if (!param.getQuadraCfa()) {
1183 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) {
1184 pp_featuremask.feature_mask = 0;
1185 pp_featuremask.feature_mask |= CAM_QCOM_FEATURE_METADATA_PROCESSING;
1186 }
1187 } else {
1188 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) {
1189 // First reprocess pass in quadra CFA mode
1190 // Skip processing of the offline metadata for first pass,
1191 pp_featuremask.feature_mask = 0;
1192 pp_featuremask.feature_mask |= CAM_QCOM_FEATURE_METADATA_BYPASS;
1193 } else if (pStream->isOrignalTypeOf(CAM_STREAM_TYPE_METADATA)) {
1194 // Second reprocess pass in quadra CFA mode
1195 // offline Metadata processing needed for second pass.
1196 // offline meta data will be copied from backend.
1197 pp_featuremask.feature_mask = 0;
1198 pp_featuremask.feature_mask |= CAM_QCOM_FEATURE_METADATA_PROCESSING;
1199 }
1200 }
1201
1202 pStreamInfoBuf = allocator.allocateStreamInfoBuf(CAM_STREAM_TYPE_OFFLINE_PROC);
1203 if (pStreamInfoBuf == NULL) {
1204 LOGE("no mem for stream info buf");
1205 rc = NO_MEMORY;
1206 break;
1207 }
1208
1209 streamInfo = (cam_stream_info_t *)pStreamInfoBuf->getPtr(0);
1210 memset(streamInfo, 0, sizeof(cam_stream_info_t));
1211 streamInfo->stream_type = CAM_STREAM_TYPE_OFFLINE_PROC;
1212 // Enable CPP high performance mode to put it in turbo frequency mode for
1213 // burst/longshot/HDR snapshot cases
1214 streamInfo->perf_mode = CAM_PERF_HIGH_PERFORMANCE;
1215 if (param.getofflineRAW() && (pStream->isTypeOf(CAM_STREAM_TYPE_RAW)
1216 || pStream->isOrignalTypeOf(CAM_STREAM_TYPE_RAW))) {
1217 if (pp_featuremask.feature_mask & CAM_QCOM_FEATURE_QUADRA_CFA) {
1218 param.getStreamFormat(CAM_STREAM_TYPE_OFFLINE_PROC, streamInfo->fmt);
1219 } else {
1220 streamInfo->fmt = CAM_FORMAT_YUV_420_NV21;
1221 }
1222 } else {
1223 rc = pStream->getFormat(streamInfo->fmt);
1224 }
1225
1226 if (pStream->isTypeOf(CAM_STREAM_TYPE_PREVIEW) ||
1227 pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW) ||
1228 pStream->isOrignalTypeOf(CAM_STREAM_TYPE_PREVIEW) ||
1229 pStream->isOrignalTypeOf(CAM_STREAM_TYPE_POSTVIEW)) {
1230 if (pp_featuremask.feature_mask & CAM_QCOM_FEATURE_SCALE) {
1231 param.getThumbnailSize(&(streamInfo->dim.width),
1232 &(streamInfo->dim.height));
1233 } else {
1234 pStream->getFrameDimension(streamInfo->dim);
1235 }
1236 } else {
1237 if ((param.isPostProcScaling() || param.isDCmAsymmetricSnapMode()) &&
1238 (pp_featuremask.feature_mask & CAM_QCOM_FEATURE_SCALE)) {
1239 rc = param.getStreamDimension(CAM_STREAM_TYPE_OFFLINE_PROC,
1240 streamInfo->dim);
1241 } else if ((param.getofflineRAW()) &&
1242 ((pStream->isTypeOf(CAM_STREAM_TYPE_RAW)) ||
1243 (pStream->isOrignalTypeOf(CAM_STREAM_TYPE_RAW)))) {
1244 if ((param.getQuadraCfa()) &&
1245 (pp_featuremask.feature_mask & CAM_QCOM_FEATURE_QUADRA_CFA)) {
1246 rc = pStream->getFrameDimension(streamInfo->dim);
1247 } else {
1248 param.getStreamDimension(CAM_STREAM_TYPE_SNAPSHOT,streamInfo->dim);
1249 }
1250 } else {
1251 rc = pStream->getFrameDimension(streamInfo->dim);
1252 }
1253 }
1254
1255 if ( contStream ) {
1256 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
1257 streamInfo->num_of_burst = 0;
1258 } else {
1259 streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
1260 streamInfo->num_of_burst = burstNum;
1261 }
1262 streamInfo->num_bufs = minStreamBufNum;
1263 streamInfo->buf_cnt = streamInfo->num_bufs;
1264
1265 cam_stream_reproc_config_t rp_cfg;
1266 memset(&rp_cfg, 0, sizeof(cam_stream_reproc_config_t));
1267 if (offline) {
1268 cam_frame_len_offset_t offset;
1269 memset(&offset, 0, sizeof(cam_frame_len_offset_t));
1270
1271 rp_cfg.pp_type = CAM_OFFLINE_REPROCESS_TYPE;
1272 pStream->getFormat(rp_cfg.offline.input_fmt);
1273 pStream->getFrameDimension(rp_cfg.offline.input_dim);
1274 pStream->getFrameOffset(offset);
1275 rp_cfg.offline.input_buf_planes.plane_info = offset;
1276 rp_cfg.offline.input_type = pStream->getMyOriginalType();
1277 //For input metadata + input buffer
1278 rp_cfg.offline.num_of_bufs = 2;
1279 } else {
1280 rp_cfg.pp_type = CAM_ONLINE_REPROCESS_TYPE;
1281 rp_cfg.online.input_stream_id = pStream->getMyServerID();
1282 rp_cfg.online.input_stream_type = pStream->getMyOriginalType();
1283 }
1284 param.getStreamRotation(streamInfo->stream_type,
1285 streamInfo->pp_config, streamInfo->dim);
1286 streamInfo->reprocess_config = rp_cfg;
1287 streamInfo->reprocess_config.pp_feature_config = pp_featuremask;
1288
1289 if (!(pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT)
1290 || pStream->isOrignalTypeOf(CAM_STREAM_TYPE_SNAPSHOT)
1291 || pStream->isTypeOf(CAM_STREAM_TYPE_RAW)
1292 || pStream->isOrignalTypeOf(CAM_STREAM_TYPE_RAW))) {
1293 // CAC, SHARPNESS, FLIP and WNR would have been already applied -
1294 // on preview/postview stream in realtime. Need not apply again.
1295 streamInfo->reprocess_config.pp_feature_config.feature_mask &=
1296 ~CAM_QCOM_FEATURE_CAC;
1297 streamInfo->reprocess_config.pp_feature_config.feature_mask &=
1298 ~CAM_QCOM_FEATURE_SHARPNESS;
1299 streamInfo->reprocess_config.pp_feature_config.feature_mask &=
1300 ~CAM_QCOM_FEATURE_FLIP;
1301 //Don't do WNR for thumbnail
1302 streamInfo->reprocess_config.pp_feature_config.feature_mask &=
1303 ~CAM_QCOM_FEATURE_DENOISE2D;
1304 streamInfo->reprocess_config.pp_feature_config.feature_mask &=
1305 ~CAM_QCOM_FEATURE_CDS;
1306 streamInfo->reprocess_config.pp_feature_config.feature_mask &=
1307 ~CAM_QCOM_FEATURE_DSDN;
1308 //No need of RAW processing for other than RAW streams
1309 streamInfo->reprocess_config.pp_feature_config.feature_mask &=
1310 ~CAM_QCOM_FEATURE_RAW_PROCESSING;
1311
1312 if (param.isHDREnabled()
1313 && !param.isHDRThumbnailProcessNeeded()){
1314 streamInfo->reprocess_config.pp_feature_config.feature_mask
1315 &= ~CAM_QCOM_FEATURE_HDR;
1316 }
1317 }
1318
1319 cam_stream_type_t type = CAM_STREAM_TYPE_DEFAULT;
1320 if (offline) {
1321 type = streamInfo->reprocess_config.offline.input_type;
1322 } else {
1323 type = streamInfo->reprocess_config.online.input_stream_type;
1324 }
1325 if (type == CAM_STREAM_TYPE_SNAPSHOT) {
1326 int flipMode = param.getFlipMode(type);
1327 if (flipMode > 0) {
1328 streamInfo->reprocess_config.pp_feature_config.feature_mask |=
1329 CAM_QCOM_FEATURE_FLIP;
1330 streamInfo->reprocess_config.pp_feature_config.flip = (uint32_t)flipMode;
1331 }
1332 }
1333
1334 if ((streamInfo->reprocess_config.pp_feature_config.feature_mask
1335 & CAM_QCOM_FEATURE_SCALE)
1336 && param.isReprocScaleEnabled()
1337 && param.isUnderReprocScaling()) {
1338 //we only Scale Snapshot frame
1339 if (pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT)) {
1340 streamInfo->dim.width =
1341 streamInfo->reprocess_config.pp_feature_config.scale_param.output_width;
1342 streamInfo->dim.height =
1343 streamInfo->reprocess_config.pp_feature_config.scale_param.output_height;
1344 }
1345 LOGH("stream width=%d, height=%d.",
1346 streamInfo->dim.width, streamInfo->dim.height);
1347 }
1348
1349 // save source stream handler
1350 if (mDualChannel) {
1351 mSrcStreamHandles[mStreams.size()] = pStream->getMyHandle();
1352 } else if (get_main_camera_handle(pStream->getMyHandle())) {
1353 mSrcStreamHandles[mStreams.size()] =
1354 get_main_camera_handle(pStream->getMyHandle());
1355 } else if (get_aux_camera_handle(pStream->getMyHandle())) {
1356 mSrcStreamHandles[mStreams.size()] =
1357 get_aux_camera_handle(pStream->getMyHandle());
1358 } else {
1359 LOGE("Invalid Handle. ");
1360 rc = BAD_VALUE;
1361 break;
1362 }
1363
1364 mSrcStreamHandles[mStreams.size()] = pStream->getMyHandle();
1365 pMiscBuf = allocator.allocateMiscBuf(streamInfo);
1366
1367 if (offline) {
1368 LOGH("Configure Reprocessing Input stream = %d Input: res = %dX%d,"
1369 "fmt = %d, buf_cnt = %d",
1370 streamInfo->reprocess_config.offline.input_type,
1371 rp_cfg.offline.input_dim.width,
1372 rp_cfg.offline.input_dim.height,
1373 rp_cfg.offline.input_fmt, rp_cfg.offline.num_of_bufs);
1374 }
1375
1376 LOGH("Configure Reprocessing Output: stream = %d, res = %dX%d, fmt = %d,"
1377 "type = %d buf_cnt = %d",
1378 pStream->getMyOriginalType(), streamInfo->dim.width,
1379 streamInfo->dim.height, streamInfo->fmt, type, minStreamBufNum);
1380
1381 // add reprocess stream
1382 if (streamInfo->reprocess_config.pp_feature_config.feature_mask
1383 & CAM_QCOM_FEATURE_ROTATION) {
1384 rc = addStream(allocator, pStreamInfoBuf, pMiscBuf,
1385 &padding, NULL, NULL, false, false,
1386 streamInfo->reprocess_config.pp_feature_config.rotation,
1387 pStream->getMyCamType());
1388 } else {
1389 rc = addStream(allocator, pStreamInfoBuf, pMiscBuf,
1390 &padding, NULL, NULL, false, false, ROTATE_0,
1391 pStream->getMyCamType());
1392 }
1393 if (rc != NO_ERROR) {
1394 LOGE("add reprocess stream failed, ret = %d", rc);
1395 break;
1396 }
1397 }
1398 }
1399
1400 if (rc == NO_ERROR) {
1401 m_pSrcChannel = pSrcChannel;
1402 }
1403 return rc;
1404 }
1405
1406 /*===========================================================================
1407 * FUNCTION : getStreamBySrouceHandle
1408 *
1409 * DESCRIPTION: find reprocess stream by its source stream handle
1410 *
1411 * PARAMETERS :
1412 * @srcHandle : source stream handle
1413 *
1414 * RETURN : ptr to reprocess stream if found. NULL if not found
1415 *==========================================================================*/
getStreamBySrouceHandle(uint32_t srcHandle)1416 QCameraStream * QCameraReprocessChannel::getStreamBySrouceHandle(uint32_t srcHandle)
1417 {
1418 QCameraStream *pStream = NULL;
1419
1420 for (size_t i = 0; i < mStreams.size(); i++) {
1421 if (validate_handle(mSrcStreamHandles[i], srcHandle)) {
1422 pStream = mStreams[i];
1423 break;
1424 }
1425 }
1426
1427 return pStream;
1428 }
1429
1430 /*===========================================================================
1431 * FUNCTION : stop
1432 *
1433 * DESCRIPTION: stop channel and unmap offline buffers
1434 *
1435 * PARAMETERS : none
1436 *
1437 * RETURN : int32_t type of status
1438 * NO_ERROR -- success
1439 * none-zero failure code
1440 *==========================================================================*/
stop()1441 int32_t QCameraReprocessChannel::stop()
1442 {
1443 int32_t rc = QCameraChannel::stop();
1444
1445 if (!mOfflineBuffers.empty()) {
1446 QCameraStream *stream = NULL;
1447 List<OfflineBuffer>::iterator it = mOfflineBuffers.begin();
1448 int error = NO_ERROR;
1449 for( ; it != mOfflineBuffers.end(); it++) {
1450 stream = (*it).stream;
1451 if (NULL != stream) {
1452 error = stream->unmapBuf((*it).type,
1453 (*it).index,
1454 -1);
1455 if (NO_ERROR != error) {
1456 LOGE("Error during offline buffer unmap %d",
1457 error);
1458 }
1459 }
1460 }
1461 mOfflineBuffers.clear();
1462 }
1463 return rc;
1464 }
1465
1466 /*===========================================================================
1467 * FUNCTION : doReprocessOffline
1468 *
1469 * DESCRIPTION: request to do offline reprocess on the frame
1470 *
1471 * PARAMETERS :
1472 * @frame : frame to be performed a reprocess
1473 * @meta_buf : Metadata buffer for reprocessing
1474 * @pStream : Actual reprocess stream
1475 *
1476 * RETURN : int32_t type of status
1477 * NO_ERROR -- success
1478 * none-zero failure code
1479 *==========================================================================*/
doReprocessOffline(mm_camera_buf_def_t * frame,mm_camera_buf_def_t * meta_buf,QCameraStream * pStream)1480 int32_t QCameraReprocessChannel::doReprocessOffline(mm_camera_buf_def_t *frame,
1481 mm_camera_buf_def_t *meta_buf, QCameraStream *pStream)
1482 {
1483 int32_t rc = 0;
1484 OfflineBuffer mappedBuffer;
1485 uint32_t buf_index = 0;
1486 uint32_t meta_buf_index = 0;
1487
1488 if ((frame == NULL) || (meta_buf == NULL)) {
1489 LOGE("Invalid Input Paramters");
1490 return INVALID_OPERATION;
1491 }
1492
1493 if (pStream == NULL) {
1494 pStream = getStreamBySrouceHandle(frame->stream_id);
1495 if (pStream == NULL) {
1496 LOGE("Input validation failed.");
1497 return INVALID_OPERATION;
1498 }
1499 }
1500
1501 if (!mOfflineBuffers.empty()) {
1502 List<OfflineBuffer>::iterator it = mOfflineBuffers.begin();
1503 for( ; it != mOfflineBuffers.end(); it++) {
1504 buf_index = (buf_index < ((*it).index)) ? ((*it).index) : buf_index;
1505 }
1506 buf_index += 1;
1507 }
1508
1509 meta_buf_index = buf_index;
1510 if (meta_buf != NULL) {
1511 rc = pStream->mapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_META_BUF,
1512 meta_buf_index,
1513 -1,
1514 meta_buf->fd,
1515 meta_buf->buffer,
1516 meta_buf->frame_len);
1517 if (NO_ERROR != rc ) {
1518 LOGE("Error during metadata buffer mapping");
1519 rc = -1;
1520 return rc;
1521 }
1522
1523 mappedBuffer.index = meta_buf_index;
1524 mappedBuffer.stream = pStream;
1525 mappedBuffer.type = CAM_MAPPING_BUF_TYPE_OFFLINE_META_BUF;
1526 mOfflineBuffers.push_back(mappedBuffer);
1527 buf_index += 1;
1528 }
1529
1530 rc = pStream->mapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF,
1531 buf_index,
1532 -1,
1533 frame->fd,
1534 frame->buffer,
1535 frame->frame_len);
1536 if (NO_ERROR != rc ) {
1537 LOGE("Error during reprocess input buffer mapping");
1538 rc = -1;
1539 return rc;
1540 }
1541 mappedBuffer.index = buf_index;
1542 mappedBuffer.stream = pStream;
1543 mappedBuffer.type = CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF;
1544 mOfflineBuffers.push_back(mappedBuffer);
1545
1546 cam_stream_parm_buffer_t param;
1547 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t));
1548
1549 param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS;
1550 param.reprocess.buf_index = buf_index;
1551 param.reprocess.frame_idx = frame->frame_idx;
1552 param.reprocess.is_uv_subsampled = frame->is_uv_subsampled;
1553 cam_stream_info_t *streamInfo =
1554 reinterpret_cast<cam_stream_info_t *>(pStream->getStreamInfoBuf()->getPtr(0));
1555
1556 if ((pStream->isOrignalTypeOf(CAM_STREAM_TYPE_METADATA)) && streamInfo &&
1557 (streamInfo->reprocess_config.pp_feature_config.feature_mask &
1558 CAM_QCOM_FEATURE_METADATA_BYPASS)) {
1559 LOGH("set meta bypass for quadra cfa first pass");
1560 // Backend will skip processing of metadata for first pass
1561 param.reprocess.is_offline_meta_bypass = 1;
1562 }
1563 if (meta_buf != NULL) {
1564 param.reprocess.meta_present = 1;
1565 param.reprocess.meta_buf_index = meta_buf_index;
1566 }
1567
1568 LOGI("Offline reprocessing id = %d buf Id = %d meta index = %d type = %d",
1569 param.reprocess.frame_idx, param.reprocess.buf_index,
1570 param.reprocess.meta_buf_index, pStream->getMyOriginalType());
1571
1572 rc = pStream->setParameter(param);
1573 if (rc != NO_ERROR) {
1574 LOGE("stream setParameter for reprocess failed");
1575 return rc;
1576 }
1577 return rc;
1578 }
1579
1580 /*===========================================================================
1581 * FUNCTION : doReprocessOffline
1582 *
1583 * DESCRIPTION: request to do offline reprocess on the frame
1584 *
1585 * PARAMETERS :
1586 * @frame : frame to be performed a reprocess
1587 * @meta_buf : Metadata buffer for reprocessing
1588 * @mParameter : camera parameters
1589 *
1590 * RETURN : int32_t type of status
1591 * NO_ERROR -- success
1592 * none-zero failure code
1593 *==========================================================================*/
doReprocessOffline(mm_camera_super_buf_t * frame,mm_camera_buf_def_t * meta_buf,QCameraParametersIntf & mParameter)1594 int32_t QCameraReprocessChannel::doReprocessOffline(mm_camera_super_buf_t *frame,
1595 mm_camera_buf_def_t *meta_buf, QCameraParametersIntf &mParameter)
1596 {
1597 int32_t rc = 0;
1598 QCameraStream *pStream = NULL;
1599
1600 if (mStreams.size() < 1) {
1601 LOGE("No reprocess streams");
1602 return -1;
1603 }
1604 if (m_pSrcChannel == NULL) {
1605 LOGE("No source channel for reprocess");
1606 return -1;
1607 }
1608
1609 if (frame == NULL) {
1610 LOGE("Invalid source frame");
1611 return BAD_VALUE;
1612 }
1613
1614 for (uint32_t i = 0; i < frame->num_bufs; i++) {
1615 pStream = getStreamBySrouceHandle(frame->bufs[i]->stream_id);
1616 if ((pStream != NULL) &&
1617 (validate_handle(m_handle,pStream->getChannelHandle()))) {
1618 if (mParameter.getofflineRAW() &&
1619 !((pStream->isOrignalTypeOf(CAM_STREAM_TYPE_RAW))
1620 || (pStream->isOrignalTypeOf(CAM_STREAM_TYPE_METADATA)))) {
1621 continue;
1622 }
1623
1624 if ((pStream->isOrignalTypeOf(CAM_STREAM_TYPE_METADATA)
1625 && ((mParameter.getManualCaptureMode()
1626 < CAM_MANUAL_CAPTURE_TYPE_3) && (!mParameter.getQuadraCfa())))
1627 || (pStream->isTypeOf(CAM_STREAM_TYPE_ANALYSIS))) {
1628 // Skip metadata for reprocess now because PP module cannot handle meta data
1629 // May need furthur discussion if Imaginglib need meta data
1630 // Do not skip metadata for manual capture or quadra CFA mode.
1631 continue;
1632 }
1633
1634 // Update Metadata
1635 if (meta_buf != NULL) {
1636 uint32_t stream_id = frame->bufs[i]->stream_id;
1637 QCameraStream *srcStream =
1638 m_pSrcChannel->getStreamByHandle(stream_id);
1639 metadata_buffer_t *pMetaData =
1640 (metadata_buffer_t *)meta_buf->buffer;
1641 if ((NULL != pMetaData) && (NULL != srcStream)) {
1642 IF_META_AVAILABLE(cam_crop_data_t, crop,
1643 CAM_INTF_META_CROP_DATA, pMetaData) {
1644 if (MAX_NUM_STREAMS > crop->num_of_streams) {
1645 for (int j = 0; j < MAX_NUM_STREAMS; j++) {
1646 if (crop->crop_info[j].stream_id ==
1647 srcStream->getMyServerID()) {
1648 // Store crop/roi information for offline reprocess
1649 // in the reprocess stream slot
1650 crop->crop_info[crop->num_of_streams].crop =
1651 crop->crop_info[j].crop;
1652 crop->crop_info[crop->num_of_streams].roi_map =
1653 crop->crop_info[j].roi_map;
1654 for (uint8_t k = 0; k < mStreams.size(); k++) {
1655 if (srcStream->getMyType() ==
1656 mStreams[k]->getMyOriginalType()) {
1657 crop->crop_info[crop->num_of_streams].stream_id =
1658 mStreams[k]->getMyServerID();
1659 break;
1660 }
1661 }
1662 crop->num_of_streams++;
1663 break;
1664 }
1665 }
1666 } else {
1667 LOGE("No space to add reprocess stream crop/roi information");
1668 }
1669 }
1670 }
1671 } else {
1672 LOGE("Metadata NULL");
1673 }
1674
1675 if (mParameter.getofflineRAW()) {
1676 //For offline RAW reprocessing, make sure cache is clean & invalidated
1677 frame->bufs[i]->cache_flags |= CPU_HAS_READ_WRITTEN;
1678 }
1679 //Do Cache ops before sending to reprocess
1680 if (frame->bufs[i] != NULL) {
1681 pStream->handleCacheOps(frame->bufs[i]);
1682 }
1683 rc = doReprocessOffline (frame->bufs[i], meta_buf, pStream);
1684 }
1685 }
1686 return rc;
1687 }
1688
1689 /*===========================================================================
1690 * FUNCTION : doReprocess
1691 *
1692 * DESCRIPTION: request to do a reprocess on the frame
1693 *
1694 * PARAMETERS :
1695 * @frame : frame to be performed a reprocess
1696 * @mParameter : camera parameters
1697 * @pMetaStream: Metadata stream handle
1698 * @meta_buf_index : Metadata buffer index
1699 *
1700 * RETURN : int32_t type of status
1701 * NO_ERROR -- success
1702 * none-zero failure code
1703 *==========================================================================*/
doReprocess(mm_camera_super_buf_t * frame,QCameraParametersIntf & mParameter,QCameraStream * pMetaStream,uint8_t meta_buf_index)1704 int32_t QCameraReprocessChannel::doReprocess(mm_camera_super_buf_t *frame,
1705 QCameraParametersIntf &mParameter, QCameraStream *pMetaStream,
1706 uint8_t meta_buf_index)
1707 {
1708 int32_t rc = 0;
1709 if (mStreams.size() < 1) {
1710 LOGE("No reprocess streams");
1711 return -1;
1712 }
1713 if (m_pSrcChannel == NULL) {
1714 LOGE("No source channel for reprocess");
1715 return -1;
1716 }
1717
1718 if (pMetaStream == NULL) {
1719 LOGW("Null Metadata buffer for processing");
1720 }
1721
1722 for (uint32_t i = 0; i < frame->num_bufs; i++) {
1723 QCameraStream *pStream = getStreamBySrouceHandle(frame->bufs[i]->stream_id);
1724 if ((pStream != NULL) &&
1725 (validate_handle(m_handle, pStream->getChannelHandle()))) {
1726 if (mParameter.getofflineRAW() && !((pStream->isOrignalTypeOf(CAM_STREAM_TYPE_RAW))
1727 || (pStream->isOrignalTypeOf(CAM_STREAM_TYPE_POSTVIEW))
1728 || (pStream->isOrignalTypeOf(CAM_STREAM_TYPE_METADATA)))) {
1729 //Skip all the stream other than RAW and POSTVIEW incase of offline of RAW
1730 continue;
1731 }
1732 if ((pStream->isOrignalTypeOf(CAM_STREAM_TYPE_METADATA)
1733 && ((mParameter.getManualCaptureMode()
1734 < CAM_MANUAL_CAPTURE_TYPE_3) && (!mParameter.getQuadraCfa())))
1735 || (pStream->isTypeOf(CAM_STREAM_TYPE_ANALYSIS))) {
1736 // Skip metadata for reprocess now because PP module cannot handle meta data
1737 // May need furthur discussion if Imaginglib need meta data
1738 // Do not skip metadata for manual capture or quadra CFA mode.
1739 continue;
1740 }
1741
1742 //Do Cache ops before sending to reprocess
1743 if (frame->bufs[i] != NULL) {
1744 pStream->handleCacheOps(frame->bufs[i]);
1745 }
1746
1747 cam_stream_parm_buffer_t param;
1748 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t));
1749 param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS;
1750 param.reprocess.buf_index = frame->bufs[i]->buf_idx;
1751 param.reprocess.frame_idx = frame->bufs[i]->frame_idx;
1752 param.reprocess.is_uv_subsampled = frame->bufs[i]->is_uv_subsampled;
1753 if (pMetaStream != NULL) {
1754 // we have meta data frame bundled, sent together with reprocess frame
1755 param.reprocess.meta_present = 1;
1756 param.reprocess.meta_stream_handle = pMetaStream->getMyServerID();
1757 param.reprocess.meta_buf_index = meta_buf_index;
1758 }
1759
1760 LOGI("Online reprocessing id = %d buf Id = %d meta index = %d type = %d",
1761 param.reprocess.frame_idx, param.reprocess.buf_index,
1762 param.reprocess.meta_buf_index, pStream->getMyOriginalType());
1763
1764 rc = pStream->setParameter(param);
1765 if (rc != NO_ERROR) {
1766 LOGE("stream setParameter for reprocess failed");
1767 break;
1768 }
1769 }
1770 }
1771 return rc;
1772 }
1773
1774 /*===========================================================================
1775 * FUNCTION : doReprocess
1776 *
1777 * DESCRIPTION: request to do a reprocess on the frame
1778 *
1779 * PARAMETERS :
1780 * @buf_fd : fd to the input buffer that needs reprocess
1781 * @buffer : buffer pointer of actual buffer
1782 * @buf_lenght : length of the input buffer
1783 * @ret_val : result of reprocess.
1784 * Example: Could be faceID in case of register face image.
1785 *
1786 * RETURN : int32_t type of status
1787 * NO_ERROR -- success
1788 * none-zero failure code
1789 *==========================================================================*/
doReprocess(int buf_fd,void * buffer,size_t buf_length,int32_t & ret_val)1790 int32_t QCameraReprocessChannel::doReprocess(int buf_fd, void *buffer,
1791 size_t buf_length, int32_t &ret_val)
1792 {
1793 int32_t rc = 0;
1794 if (mStreams.size() < 1) {
1795 LOGE("No reprocess streams");
1796 return -1;
1797 }
1798
1799 uint32_t buf_idx = 0;
1800 for (size_t i = 0; i < mStreams.size(); i++) {
1801 if ((mStreams[i] != NULL) &&
1802 (validate_handle(m_handle, mStreams[i]->getChannelHandle()))) {
1803 continue;
1804 }
1805 rc = mStreams[i]->mapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF,
1806 buf_idx, -1,
1807 buf_fd, buffer, buf_length);
1808
1809 if (rc == NO_ERROR) {
1810 cam_stream_parm_buffer_t param;
1811 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t));
1812 param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS;
1813 param.reprocess.buf_index = buf_idx;
1814 rc = mStreams[i]->setParameter(param);
1815 if (rc == NO_ERROR) {
1816 ret_val = param.reprocess.ret_val;
1817 }
1818 mStreams[i]->unmapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF,
1819 buf_idx, -1);
1820 }
1821 }
1822 return rc;
1823 }
1824
1825 }; // namespace qcamera
1826