1 /* Copyright (c) 2012-2013, 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
59 m_handle = 0;
60 m_numStreams = 0;
61 memset(mStreams, 0, sizeof(mStreams));
62 }
63
64 /*===========================================================================
65 * FUNCTION : QCameraChannel
66 *
67 * DESCRIPTION: default constrcutor of QCameraChannel
68 *
69 * PARAMETERS : none
70 *
71 * RETURN : none
72 *==========================================================================*/
QCameraChannel()73 QCameraChannel::QCameraChannel()
74 {
75 m_camHandle = 0;
76 m_camOps = NULL;
77 m_bIsActive = false;
78
79 m_handle = 0;
80 m_numStreams = 0;
81 memset(mStreams, 0, sizeof(mStreams));
82 }
83
84 /*===========================================================================
85 * FUNCTION : ~QCameraChannel
86 *
87 * DESCRIPTION: destructor of QCameraChannel
88 *
89 * PARAMETERS : none
90 *
91 * RETURN : none
92 *==========================================================================*/
~QCameraChannel()93 QCameraChannel::~QCameraChannel()
94 {
95 if (m_bIsActive) {
96 stop();
97 }
98
99 for (int i = 0; i < m_numStreams; i++) {
100 if (mStreams[i] != NULL) {
101 delete mStreams[i];
102 mStreams[i] = 0;
103 }
104 }
105 m_numStreams = 0;
106 m_camOps->delete_channel(m_camHandle, m_handle);
107 m_handle = 0;
108 }
109
110 /*===========================================================================
111 * FUNCTION : init
112 *
113 * DESCRIPTION: initialization of channel
114 *
115 * PARAMETERS :
116 * @attr : channel bundle attribute setting
117 * @dataCB : data notify callback
118 * @userData: user data ptr
119 *
120 * RETURN : int32_t type of status
121 * NO_ERROR -- success
122 * none-zero failure code
123 *==========================================================================*/
init(mm_camera_channel_attr_t * attr,mm_camera_buf_notify_t dataCB,void * userData)124 int32_t QCameraChannel::init(mm_camera_channel_attr_t *attr,
125 mm_camera_buf_notify_t dataCB,
126 void *userData)
127 {
128 m_handle = m_camOps->add_channel(m_camHandle,
129 attr,
130 dataCB,
131 userData);
132 if (m_handle == 0) {
133 ALOGE("%s: Add channel failed", __func__);
134 return UNKNOWN_ERROR;
135 }
136 return NO_ERROR;
137 }
138
139 /*===========================================================================
140 * FUNCTION : addStream
141 *
142 * DESCRIPTION: add a stream into channel
143 *
144 * PARAMETERS :
145 * @allocator : stream related buffer allocator
146 * @streamInfoBuf : ptr to buf that constains stream info
147 * @minStreamBufNum: number of stream buffers needed
148 * @paddingInfo : padding information
149 * @stream_cb : stream data notify callback
150 * @userdata : user data ptr
151 *
152 * RETURN : int32_t type of status
153 * NO_ERROR -- success
154 * none-zero failure code
155 *==========================================================================*/
addStream(QCameraAllocator & allocator,QCameraHeapMemory * streamInfoBuf,uint8_t minStreamBufNum,cam_padding_info_t * paddingInfo,stream_cb_routine stream_cb,void * userdata)156 int32_t QCameraChannel::addStream(QCameraAllocator &allocator,
157 QCameraHeapMemory *streamInfoBuf,
158 uint8_t minStreamBufNum,
159 cam_padding_info_t *paddingInfo,
160 stream_cb_routine stream_cb,
161 void *userdata)
162 {
163 int32_t rc = NO_ERROR;
164 if (m_numStreams >= MAX_STREAM_NUM_IN_BUNDLE) {
165 ALOGE("%s: stream number (%d) exceeds max limit (%d)",
166 __func__, m_numStreams, MAX_STREAM_NUM_IN_BUNDLE);
167 return BAD_VALUE;
168 }
169 QCameraStream *pStream = new QCameraStream(allocator,
170 m_camHandle,
171 m_handle,
172 m_camOps,
173 paddingInfo);
174 if (pStream == NULL) {
175 ALOGE("%s: No mem for Stream", __func__);
176 return NO_MEMORY;
177 }
178
179 rc = pStream->init(streamInfoBuf, minStreamBufNum, stream_cb, userdata);
180 if (rc == 0) {
181 mStreams[m_numStreams] = pStream;
182 m_numStreams++;
183 } else {
184 delete pStream;
185 }
186 return rc;
187 }
188
189 /*===========================================================================
190 * FUNCTION : start
191 *
192 * DESCRIPTION: start channel, which will start all streams belong to this channel
193 *
194 * PARAMETERS : None
195 *
196 * RETURN : int32_t type of status
197 * NO_ERROR -- success
198 * none-zero failure code
199 *==========================================================================*/
start()200 int32_t QCameraChannel::start()
201 {
202 int32_t rc = NO_ERROR;
203
204 if (m_numStreams > 1) {
205 // there is more than one stream in the channel
206 // we need to notify mctl that all streams in this channel need to be bundled
207 cam_bundle_config_t bundleInfo;
208 memset(&bundleInfo, 0, sizeof(bundleInfo));
209 rc = m_camOps->get_bundle_info(m_camHandle, m_handle, &bundleInfo);
210 if (rc != NO_ERROR) {
211 ALOGE("%s: get_bundle_info failed", __func__);
212 return rc;
213 }
214 if (bundleInfo.num_of_streams > 1) {
215 for (int i = 0; i < bundleInfo.num_of_streams; i++) {
216 QCameraStream *pStream = getStreamByServerID(bundleInfo.stream_ids[i]);
217 if (pStream != NULL) {
218 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) {
219 // Skip metadata for reprocess now because PP module cannot handle meta data
220 // May need furthur discussion if Imaginglib need meta data
221 continue;
222 }
223
224 cam_stream_parm_buffer_t param;
225 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t));
226 param.type = CAM_STREAM_PARAM_TYPE_SET_BUNDLE_INFO;
227 param.bundleInfo = bundleInfo;
228 rc = pStream->setParameter(param);
229 if (rc != NO_ERROR) {
230 ALOGE("%s: stream setParameter for set bundle failed", __func__);
231 return rc;
232 }
233 }
234 }
235 }
236 }
237
238 for (int i = 0; i < m_numStreams; i++) {
239 if (mStreams[i] != NULL) {
240 mStreams[i]->start();
241 }
242 }
243 rc = m_camOps->start_channel(m_camHandle, m_handle);
244
245 if (rc != NO_ERROR) {
246 for (int i = 0; i < m_numStreams; i++) {
247 if (mStreams[i] != NULL) {
248 mStreams[i]->stop();
249 }
250 }
251 } else {
252 m_bIsActive = true;
253 }
254
255 return rc;
256 }
257
258 /*===========================================================================
259 * FUNCTION : stop
260 *
261 * DESCRIPTION: stop a channel, which will stop all streams belong to this channel
262 *
263 * PARAMETERS : none
264 *
265 * RETURN : int32_t type of status
266 * NO_ERROR -- success
267 * none-zero failure code
268 *==========================================================================*/
stop()269 int32_t QCameraChannel::stop()
270 {
271 int32_t rc = NO_ERROR;
272 rc = m_camOps->stop_channel(m_camHandle, m_handle);
273
274 for (int i = 0; i < m_numStreams; i++) {
275 if (mStreams[i] != NULL) {
276 mStreams[i]->stop();
277 }
278 }
279
280 m_bIsActive = false;
281 return rc;
282 }
283
284 /*===========================================================================
285 * FUNCTION : bufDone
286 *
287 * DESCRIPTION: return a stream buf back to kernel
288 *
289 * PARAMETERS :
290 * @recvd_frame : stream buf frame to be returned
291 *
292 * RETURN : int32_t type of status
293 * NO_ERROR -- success
294 * none-zero failure code
295 *==========================================================================*/
bufDone(mm_camera_super_buf_t * recvd_frame)296 int32_t QCameraChannel::bufDone(mm_camera_super_buf_t *recvd_frame)
297 {
298 int32_t rc = NO_ERROR;
299 for (int i = 0; i < recvd_frame->num_bufs; i++) {
300 if (recvd_frame->bufs[i] != NULL) {
301 for (int j = 0; j < m_numStreams; j++) {
302 if (mStreams[j] != NULL &&
303 mStreams[j]->getMyHandle() == recvd_frame->bufs[i]->stream_id) {
304 rc = mStreams[j]->bufDone(recvd_frame->bufs[i]->buf_idx);
305 break; // break loop j
306 }
307 }
308 }
309 }
310
311 return rc;
312 }
313
314 /*===========================================================================
315 * FUNCTION : processZoomDone
316 *
317 * DESCRIPTION: process zoom done event
318 *
319 * PARAMETERS :
320 * @previewWindoe : ptr to preview window ops table, needed to set preview
321 * crop information
322 * @crop_info : crop info as a result of zoom operation
323 *
324 * RETURN : int32_t type of status
325 * NO_ERROR -- success
326 * none-zero failure code
327 *==========================================================================*/
processZoomDone(preview_stream_ops_t * previewWindow,cam_crop_data_t & crop_info)328 int32_t QCameraChannel::processZoomDone(preview_stream_ops_t *previewWindow,
329 cam_crop_data_t &crop_info)
330 {
331 int32_t rc = NO_ERROR;
332 for (int i = 0; i < m_numStreams; i++) {
333 if (mStreams[i] != NULL) {
334 rc = mStreams[i]->processZoomDone(previewWindow, crop_info);
335 }
336 }
337 return rc;
338 }
339
340 /*===========================================================================
341 * FUNCTION : getStreamByHandle
342 *
343 * DESCRIPTION: return stream object by stream handle
344 *
345 * PARAMETERS :
346 * @streamHandle : stream handle
347 *
348 * RETURN : stream object. NULL if not found
349 *==========================================================================*/
getStreamByHandle(uint32_t streamHandle)350 QCameraStream *QCameraChannel::getStreamByHandle(uint32_t streamHandle)
351 {
352 for (int i = 0; i < m_numStreams; i++) {
353 if (mStreams[i] != NULL && mStreams[i]->getMyHandle() == streamHandle) {
354 return mStreams[i];
355 }
356 }
357 return NULL;
358 }
359
360 /*===========================================================================
361 * FUNCTION : getStreamByServerID
362 *
363 * DESCRIPTION: return stream object by stream server ID from daemon
364 *
365 * PARAMETERS :
366 * @serverID : stream server ID
367 *
368 * RETURN : stream object. NULL if not found
369 *==========================================================================*/
getStreamByServerID(uint32_t serverID)370 QCameraStream *QCameraChannel::getStreamByServerID(uint32_t serverID)
371 {
372 for (int i = 0; i < m_numStreams; i++) {
373 if (mStreams[i] != NULL && mStreams[i]->getMyServerID() == serverID) {
374 return mStreams[i];
375 }
376 }
377 return NULL;
378 }
379
380 /*===========================================================================
381 * FUNCTION : getStreamByIndex
382 *
383 * DESCRIPTION: return stream object by index of streams in the channel
384 *
385 * PARAMETERS :
386 * @index : index of stream in the channel
387 *
388 * RETURN : stream object. NULL if not found
389 *==========================================================================*/
getStreamByIndex(uint8_t index)390 QCameraStream *QCameraChannel::getStreamByIndex(uint8_t index)
391 {
392 if (index < m_numStreams) {
393 return mStreams[index];
394 }
395 return NULL;
396 }
397
398 /*===========================================================================
399 * FUNCTION : QCameraPicChannel
400 *
401 * DESCRIPTION: constructor of QCameraPicChannel
402 *
403 * PARAMETERS :
404 * @cam_handle : camera handle
405 * @cam_ops : ptr to camera ops table
406 *
407 * RETURN : none
408 *==========================================================================*/
QCameraPicChannel(uint32_t cam_handle,mm_camera_ops_t * cam_ops)409 QCameraPicChannel::QCameraPicChannel(uint32_t cam_handle,
410 mm_camera_ops_t *cam_ops) :
411 QCameraChannel(cam_handle, cam_ops)
412 {
413 }
414
415 /*===========================================================================
416 * FUNCTION : QCameraPicChannel
417 *
418 * DESCRIPTION: default constructor of QCameraPicChannel
419 *
420 * PARAMETERS : none
421 *
422 * RETURN : none
423 *==========================================================================*/
QCameraPicChannel()424 QCameraPicChannel::QCameraPicChannel()
425 {
426 }
427
428 /*===========================================================================
429 * FUNCTION : ~QCameraPicChannel
430 *
431 * DESCRIPTION: destructor of QCameraPicChannel
432 *
433 * PARAMETERS : none
434 *
435 * RETURN : none
436 *==========================================================================*/
~QCameraPicChannel()437 QCameraPicChannel::~QCameraPicChannel()
438 {
439 }
440
441 /*===========================================================================
442 * FUNCTION : takePicture
443 *
444 * DESCRIPTION: send request for queued snapshot frames
445 *
446 * PARAMETERS :
447 * @num_of_snapshot : number of snapshot frames requested
448 *
449 * RETURN : int32_t type of status
450 * NO_ERROR -- success
451 * none-zero failure code
452 *==========================================================================*/
takePicture(uint8_t num_of_snapshot)453 int32_t QCameraPicChannel::takePicture(uint8_t num_of_snapshot)
454 {
455 int32_t rc = m_camOps->request_super_buf(m_camHandle,
456 m_handle,
457 num_of_snapshot);
458 return rc;
459 }
460
461 /*===========================================================================
462 * FUNCTION : cancelPicture
463 *
464 * DESCRIPTION: cancel request for queued snapshot frames
465 *
466 * PARAMETERS : none
467 *
468 * RETURN : int32_t type of status
469 * NO_ERROR -- success
470 * none-zero failure code
471 *==========================================================================*/
cancelPicture()472 int32_t QCameraPicChannel::cancelPicture()
473 {
474 int32_t rc = m_camOps->cancel_super_buf_request(m_camHandle, m_handle);
475 return rc;
476 }
477
478 /*===========================================================================
479 * FUNCTION : QCameraVideoChannel
480 *
481 * DESCRIPTION: constructor of QCameraVideoChannel
482 *
483 * PARAMETERS :
484 * @cam_handle : camera handle
485 * @cam_ops : ptr to camera ops table
486 *
487 * RETURN : none
488 *==========================================================================*/
QCameraVideoChannel(uint32_t cam_handle,mm_camera_ops_t * cam_ops)489 QCameraVideoChannel::QCameraVideoChannel(uint32_t cam_handle,
490 mm_camera_ops_t *cam_ops) :
491 QCameraChannel(cam_handle, cam_ops)
492 {
493 }
494
495 /*===========================================================================
496 * FUNCTION : QCameraVideoChannel
497 *
498 * DESCRIPTION: default constructor of QCameraVideoChannel
499 *
500 * PARAMETERS : none
501 *
502 * RETURN : none
503 *==========================================================================*/
QCameraVideoChannel()504 QCameraVideoChannel::QCameraVideoChannel()
505 {
506 }
507
508 /*===========================================================================
509 * FUNCTION : ~QCameraVideoChannel
510 *
511 * DESCRIPTION: destructor of QCameraVideoChannel
512 *
513 * PARAMETERS : none
514 *
515 * RETURN : none
516 *==========================================================================*/
~QCameraVideoChannel()517 QCameraVideoChannel::~QCameraVideoChannel()
518 {
519 }
520
521 /*===========================================================================
522 * FUNCTION : releaseFrame
523 *
524 * DESCRIPTION: return video frame from app
525 *
526 * PARAMETERS :
527 * @opaque : ptr to video frame to be returned
528 * @isMetaData : if frame is a metadata or real frame
529 *
530 * RETURN : int32_t type of status
531 * NO_ERROR -- success
532 * none-zero failure code
533 *==========================================================================*/
releaseFrame(const void * opaque,bool isMetaData)534 int32_t QCameraVideoChannel::releaseFrame(const void * opaque, bool isMetaData)
535 {
536 QCameraStream *pVideoStream = NULL;
537 for (int i = 0; i < m_numStreams; i++) {
538 if (mStreams[i] != NULL && mStreams[i]->isTypeOf(CAM_STREAM_TYPE_VIDEO)) {
539 pVideoStream = mStreams[i];
540 break;
541 }
542 }
543
544 if (NULL == pVideoStream) {
545 ALOGE("%s: No video stream in the channel", __func__);
546 return BAD_VALUE;
547 }
548
549 int32_t rc = pVideoStream->bufDone(opaque, isMetaData);
550 return rc;
551 }
552
553 /*===========================================================================
554 * FUNCTION : QCameraReprocessChannel
555 *
556 * DESCRIPTION: constructor of QCameraReprocessChannel
557 *
558 * PARAMETERS :
559 * @cam_handle : camera handle
560 * @cam_ops : ptr to camera ops table
561 * @pp_mask : post-proccess feature mask
562 *
563 * RETURN : none
564 *==========================================================================*/
QCameraReprocessChannel(uint32_t cam_handle,mm_camera_ops_t * cam_ops)565 QCameraReprocessChannel::QCameraReprocessChannel(uint32_t cam_handle,
566 mm_camera_ops_t *cam_ops) :
567 QCameraChannel(cam_handle, cam_ops),
568 m_pSrcChannel(NULL)
569 {
570 memset(mSrcStreamHandles, 0, sizeof(mSrcStreamHandles));
571 }
572
573 /*===========================================================================
574 * FUNCTION : QCameraReprocessChannel
575 *
576 * DESCRIPTION: default constructor of QCameraReprocessChannel
577 *
578 * PARAMETERS : none
579 *
580 * RETURN : none
581 *==========================================================================*/
QCameraReprocessChannel()582 QCameraReprocessChannel::QCameraReprocessChannel() :
583 m_pSrcChannel(NULL)
584 {
585 }
586
587 /*===========================================================================
588 * FUNCTION : ~QCameraReprocessChannel
589 *
590 * DESCRIPTION: destructor of QCameraReprocessChannel
591 *
592 * PARAMETERS : none
593 *
594 * RETURN : none
595 *==========================================================================*/
~QCameraReprocessChannel()596 QCameraReprocessChannel::~QCameraReprocessChannel()
597 {
598 }
599
600 /*===========================================================================
601 * FUNCTION : addReprocStreamsFromSource
602 *
603 * DESCRIPTION: add reprocess streams from input source channel
604 *
605 * PARAMETERS :
606 * @allocator : stream related buffer allocator
607 * @config : pp feature configuration
608 * @pSrcChannel : ptr to input source channel that needs reprocess
609 * @minStreamBufNum: number of stream buffers needed
610 * @paddingInfo : padding information
611 *
612 * RETURN : int32_t type of status
613 * NO_ERROR -- success
614 * none-zero failure code
615 *==========================================================================*/
addReprocStreamsFromSource(QCameraAllocator & allocator,cam_pp_feature_config_t & config,QCameraChannel * pSrcChannel,uint8_t minStreamBufNum,cam_padding_info_t * paddingInfo)616 int32_t QCameraReprocessChannel::addReprocStreamsFromSource(QCameraAllocator& allocator,
617 cam_pp_feature_config_t &config,
618 QCameraChannel *pSrcChannel,
619 uint8_t minStreamBufNum,
620 cam_padding_info_t *paddingInfo)
621 {
622 int32_t rc = 0;
623 QCameraStream *pStream = NULL;
624 QCameraHeapMemory *pStreamInfoBuf = NULL;
625 cam_stream_info_t *streamInfo = NULL;
626
627 memset(mSrcStreamHandles, 0, sizeof(mSrcStreamHandles));
628
629 for (int i = 0; i < pSrcChannel->getNumOfStreams(); i++) {
630 pStream = pSrcChannel->getStreamByIndex(i);
631 if (pStream != NULL) {
632 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) {
633 // Skip metadata for reprocess now because PP module cannot handle meta data
634 // May need furthur discussion if Imaginglib need meta data
635 continue;
636 }
637
638 pStreamInfoBuf = allocator.allocateStreamInfoBuf(CAM_STREAM_TYPE_OFFLINE_PROC);
639 if (pStreamInfoBuf == NULL) {
640 ALOGE("%s: no mem for stream info buf", __func__);
641 rc = NO_MEMORY;
642 break;
643 }
644
645 streamInfo = (cam_stream_info_t *)pStreamInfoBuf->getPtr(0);
646 memset(streamInfo, 0, sizeof(cam_stream_info_t));
647 streamInfo->stream_type = CAM_STREAM_TYPE_OFFLINE_PROC;
648 rc = pStream->getFormat(streamInfo->fmt);
649 rc = pStream->getFrameDimension(streamInfo->dim);
650 streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
651 streamInfo->num_of_burst = minStreamBufNum;
652
653 streamInfo->reprocess_config.pp_type = CAM_ONLINE_REPROCESS_TYPE;
654 streamInfo->reprocess_config.online.input_stream_id = pStream->getMyServerID();
655 streamInfo->reprocess_config.online.input_stream_type = pStream->getMyType();
656 streamInfo->reprocess_config.pp_feature_config = config;
657
658 if (!(pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT) ||
659 pStream->isTypeOf(CAM_STREAM_TYPE_NON_ZSL_SNAPSHOT) ||
660 pStream->isOrignalTypeOf(CAM_STREAM_TYPE_SNAPSHOT) ||
661 pStream->isOrignalTypeOf(CAM_STREAM_TYPE_NON_ZSL_SNAPSHOT))) {
662 streamInfo->reprocess_config.pp_feature_config.feature_mask &= ~CAM_QCOM_FEATURE_CAC;
663 }
664 if (streamInfo->reprocess_config.pp_feature_config.feature_mask & CAM_QCOM_FEATURE_ROTATION) {
665 if (streamInfo->reprocess_config.pp_feature_config.rotation == ROTATE_90 ||
666 streamInfo->reprocess_config.pp_feature_config.rotation == ROTATE_270) {
667 // rotated by 90 or 270, need to switch width and height
668 int32_t temp = streamInfo->dim.height;
669 streamInfo->dim.height = streamInfo->dim.width;
670 streamInfo->dim.width = temp;
671 }
672 }
673
674 // save source stream handler
675 mSrcStreamHandles[m_numStreams] = pStream->getMyHandle();
676
677 // add reprocess stream
678 rc = addStream(allocator,
679 pStreamInfoBuf, minStreamBufNum,
680 paddingInfo,
681 NULL, NULL);
682 if (rc != NO_ERROR) {
683 ALOGE("%s: add reprocess stream failed, ret = %d", __func__, rc);
684 break;
685 }
686 }
687 }
688
689 if (rc == NO_ERROR) {
690 m_pSrcChannel = pSrcChannel;
691 }
692 return rc;
693 }
694
695 /*===========================================================================
696 * FUNCTION : getStreamBySrouceHandle
697 *
698 * DESCRIPTION: find reprocess stream by its source stream handle
699 *
700 * PARAMETERS :
701 * @srcHandle : source stream handle
702 *
703 * RETURN : ptr to reprocess stream if found. NULL if not found
704 *==========================================================================*/
getStreamBySrouceHandle(uint32_t srcHandle)705 QCameraStream * QCameraReprocessChannel::getStreamBySrouceHandle(uint32_t srcHandle)
706 {
707 QCameraStream *pStream = NULL;
708
709 for (int i = 0; i < m_numStreams; i++) {
710 if (mSrcStreamHandles[i] == srcHandle) {
711 pStream = mStreams[i];
712 break;
713 }
714 }
715
716 return pStream;
717 }
718
719 /*===========================================================================
720 * FUNCTION : doReprocess
721 *
722 * DESCRIPTION: request to do a reprocess on the frame
723 *
724 * PARAMETERS :
725 * @frame : frame to be performed a reprocess
726 *
727 * RETURN : int32_t type of status
728 * NO_ERROR -- success
729 * none-zero failure code
730 *==========================================================================*/
doReprocess(mm_camera_super_buf_t * frame)731 int32_t QCameraReprocessChannel::doReprocess(mm_camera_super_buf_t *frame)
732 {
733 int32_t rc = 0;
734 if (m_numStreams < 1) {
735 ALOGE("%s: No reprocess stream is created", __func__);
736 return -1;
737 }
738 if (m_pSrcChannel == NULL) {
739 ALOGE("%s: No source channel for reprocess", __func__);
740 return -1;
741 }
742
743 // find meta data stream and index of meta data frame in the superbuf
744 QCameraStream *pMetaStream = NULL;
745 uint8_t meta_buf_index = 0;
746 for (int i = 0; i < frame->num_bufs; i++) {
747 QCameraStream *pStream = m_pSrcChannel->getStreamByHandle(frame->bufs[i]->stream_id);
748 if (pStream != NULL) {
749 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) {
750 meta_buf_index = frame->bufs[i]->buf_idx;
751 pMetaStream = pStream;
752 break;
753 }
754 }
755 }
756
757 for (int i = 0; i < frame->num_bufs; i++) {
758 QCameraStream *pStream = getStreamBySrouceHandle(frame->bufs[i]->stream_id);
759 if (pStream != NULL) {
760 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) {
761 // Skip metadata for reprocess now because PP module cannot handle meta data
762 // May need furthur discussion if Imaginglib need meta data
763 continue;
764 }
765
766 cam_stream_parm_buffer_t param;
767 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t));
768 param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS;
769 param.reprocess.buf_index = frame->bufs[i]->buf_idx;
770 param.reprocess.frame_idx = frame->bufs[i]->frame_idx;
771 if (pMetaStream != NULL) {
772 // we have meta data frame bundled, sent together with reprocess frame
773 param.reprocess.meta_present = 1;
774 param.reprocess.meta_stream_handle = pMetaStream->getMyServerID();
775 param.reprocess.meta_buf_index = meta_buf_index;
776 }
777 rc = pStream->setParameter(param);
778 if (rc != NO_ERROR) {
779 ALOGE("%s: stream setParameter for reprocess failed", __func__);
780 break;
781 }
782 }
783 }
784 return rc;
785 }
786
787 /*===========================================================================
788 * FUNCTION : doReprocess
789 *
790 * DESCRIPTION: request to do a reprocess on the frame
791 *
792 * PARAMETERS :
793 * @buf_fd : fd to the input buffer that needs reprocess
794 * @buf_lenght : length of the input buffer
795 * @ret_val : result of reprocess.
796 * Example: Could be faceID in case of register face image.
797 *
798 * RETURN : int32_t type of status
799 * NO_ERROR -- success
800 * none-zero failure code
801 *==========================================================================*/
doReprocess(int buf_fd,uint32_t buf_length,int32_t & ret_val)802 int32_t QCameraReprocessChannel::doReprocess(int buf_fd,
803 uint32_t buf_length,
804 int32_t &ret_val)
805 {
806 int32_t rc = 0;
807 if (m_numStreams < 1) {
808 ALOGE("%s: No reprocess stream is created", __func__);
809 return -1;
810 }
811
812 uint32_t buf_idx = 0;
813 for (int i = 0; i < m_numStreams; i++) {
814 rc = mStreams[i]->mapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF,
815 buf_idx, -1,
816 buf_fd, buf_length);
817
818 if (rc == NO_ERROR) {
819 cam_stream_parm_buffer_t param;
820 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t));
821 param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS;
822 param.reprocess.buf_index = buf_idx;
823 rc = mStreams[i]->setParameter(param);
824 if (rc == NO_ERROR) {
825 ret_val = param.reprocess.ret_val;
826 }
827 mStreams[i]->unmapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF,
828 buf_idx, -1);
829 }
830 }
831 return rc;
832 }
833
834 }; // namespace qcamera
835