1 /* Copyright (c) 2012-2015, 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 }
62
63 /*===========================================================================
64 * FUNCTION : QCameraChannel
65 *
66 * DESCRIPTION: default constrcutor of QCameraChannel
67 *
68 * PARAMETERS : none
69 *
70 * RETURN : none
71 *==========================================================================*/
QCameraChannel()72 QCameraChannel::QCameraChannel()
73 {
74 m_camHandle = 0;
75 m_camOps = NULL;
76 m_bIsActive = false;
77
78 m_handle = 0;
79 }
80
81 /*===========================================================================
82 * FUNCTION : ~QCameraChannel
83 *
84 * DESCRIPTION: destructor of QCameraChannel
85 *
86 * PARAMETERS : none
87 *
88 * RETURN : none
89 *==========================================================================*/
~QCameraChannel()90 QCameraChannel::~QCameraChannel()
91 {
92 if (m_bIsActive) {
93 stop();
94 }
95 for (size_t i = 0; i < mStreams.size(); i++) {
96 if (mStreams[i] != NULL) {
97 if (m_handle == mStreams[i]->getChannelHandle()) {
98 delete mStreams[i];
99 }
100 }
101 }
102 mStreams.clear();
103 m_camOps->delete_channel(m_camHandle, m_handle);
104 m_handle = 0;
105 }
106
107 /*===========================================================================
108 * FUNCTION : deleteChannel
109 *
110 * DESCRIPTION: deletes a camera channel
111 *
112 * PARAMETERS : none
113 *
114 * RETURN : none
115 *==========================================================================*/
deleteChannel()116 void QCameraChannel::deleteChannel()
117 {
118 if (m_bIsActive) {
119 stop();
120 }
121 for (size_t i = 0; i < mStreams.size(); i++) {
122 if ((mStreams[i] != NULL) && (m_handle == mStreams[i]->getChannelHandle())) {
123 mStreams[i]->deleteStream();
124 }
125 }
126 m_camOps->delete_channel(m_camHandle, m_handle);
127 }
128
129 /*===========================================================================
130 * FUNCTION : init
131 *
132 * DESCRIPTION: initialization of channel
133 *
134 * PARAMETERS :
135 * @attr : channel bundle attribute setting
136 * @dataCB : data notify callback
137 * @userData: user data ptr
138 *
139 * RETURN : int32_t type of status
140 * NO_ERROR -- success
141 * none-zero failure code
142 *==========================================================================*/
init(mm_camera_channel_attr_t * attr,mm_camera_buf_notify_t dataCB,void * userData)143 int32_t QCameraChannel::init(mm_camera_channel_attr_t *attr,
144 mm_camera_buf_notify_t dataCB,
145 void *userData)
146 {
147 m_handle = m_camOps->add_channel(m_camHandle,
148 attr,
149 dataCB,
150 userData);
151 if (m_handle == 0) {
152 ALOGE("%s: Add channel failed", __func__);
153 return UNKNOWN_ERROR;
154 }
155 return NO_ERROR;
156 }
157
158 /*===========================================================================
159 * FUNCTION : addStream
160 *
161 * DESCRIPTION: add a stream into channel
162 *
163 * PARAMETERS :
164 * @allocator : stream related buffer allocator
165 * @streamInfoBuf : ptr to buf that contains stream info
166 * @miscBuf : ptr to buf that contains misc buffers
167 * @minStreamBufNum: number of stream buffers needed
168 * @paddingInfo : padding information
169 * @stream_cb : stream data notify callback
170 * @userdata : user data ptr
171 * @bDynAllocBuf : flag indicating if allow allocate buffers in 2 steps
172 * @online_rotation: rotation applied online
173 *
174 * RETURN : int32_t type of status
175 * NO_ERROR -- success
176 * none-zero failure code
177 *==========================================================================*/
addStream(QCameraAllocator & allocator,QCameraHeapMemory * streamInfoBuf,QCameraHeapMemory * miscBuf,uint8_t minStreamBufNum,cam_padding_info_t * paddingInfo,stream_cb_routine stream_cb,void * userdata,bool bDynAllocBuf,bool bDeffAlloc,cam_rotation_t online_rotation)178 int32_t QCameraChannel::addStream(QCameraAllocator &allocator,
179 QCameraHeapMemory *streamInfoBuf, QCameraHeapMemory *miscBuf,
180 uint8_t minStreamBufNum, cam_padding_info_t *paddingInfo,
181 stream_cb_routine stream_cb, void *userdata, bool bDynAllocBuf,
182 bool bDeffAlloc, cam_rotation_t online_rotation)
183 {
184 int32_t rc = NO_ERROR;
185 if (mStreams.size() >= MAX_STREAM_NUM_IN_BUNDLE) {
186 ALOGE("%s: stream number (%zu) exceeds max limit (%d)",
187 __func__, mStreams.size(), MAX_STREAM_NUM_IN_BUNDLE);
188 if (streamInfoBuf != NULL) {
189 streamInfoBuf->deallocate();
190 delete streamInfoBuf;
191 streamInfoBuf = NULL;
192 }
193 return BAD_VALUE;
194 }
195 QCameraStream *pStream = new QCameraStream(allocator,
196 m_camHandle, m_handle, m_camOps, paddingInfo, bDeffAlloc,
197 online_rotation);
198 if (pStream == NULL) {
199 ALOGE("%s: No mem for Stream", __func__);
200 if (streamInfoBuf != NULL) {
201 streamInfoBuf->deallocate();
202 delete streamInfoBuf;
203 streamInfoBuf = NULL;
204 }
205 return NO_MEMORY;
206 }
207
208 rc = pStream->init(streamInfoBuf, miscBuf, minStreamBufNum,
209 stream_cb, userdata, bDynAllocBuf);
210 if (rc == 0) {
211 mStreams.add(pStream);
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 for (size_t i = 0; i < mStreams.size(); ++i) {
232 if ( mStreams[i]->isDeffered() ) {
233 rc = mStreams[i]->configStream();
234 if (rc != NO_ERROR) {
235 break;
236 }
237 }
238 }
239 return rc;
240 }
241
242 /*===========================================================================
243 * FUNCTION : linkStream
244 *
245 * DESCRIPTION: link a stream into channel
246 *
247 * PARAMETERS :
248 * @ch : Channel which the stream belongs to
249 * @stream : Stream which needs to be linked
250 *
251 * RETURN : int32_t type of status
252 * NO_ERROR -- success
253 * none-zero failure code
254 *==========================================================================*/
linkStream(QCameraChannel * ch,QCameraStream * stream)255 int32_t QCameraChannel::linkStream(QCameraChannel *ch, QCameraStream *stream)
256 {
257 int32_t rc = NO_ERROR;
258
259 if ((0 == m_handle) || (NULL == ch) || (NULL == stream)) {
260 return NO_INIT;
261 }
262
263 int32_t handle = m_camOps->link_stream(m_camHandle,
264 ch->getMyHandle(),
265 stream->getMyHandle(),
266 m_handle);
267 if (0 == handle) {
268 ALOGE("%s : Linking of stream failed", __func__);
269 rc = INVALID_OPERATION;
270 } else {
271 mStreams.add(stream);
272 }
273
274 return rc;
275 }
276
277 /*===========================================================================
278 * FUNCTION : start
279 *
280 * DESCRIPTION: start channel, which will start all streams belong to this channel
281 *
282 * PARAMETERS : None
283 *
284 * RETURN : int32_t type of status
285 * NO_ERROR -- success
286 * none-zero failure code
287 *==========================================================================*/
start()288 int32_t QCameraChannel::start()
289 {
290 int32_t rc = NO_ERROR;
291
292 if (mStreams.size() > 1) {
293 // there is more than one stream in the channel
294 // we need to notify mctl that all streams in this channel need to be bundled
295 cam_bundle_config_t bundleInfo;
296 memset(&bundleInfo, 0, sizeof(bundleInfo));
297 rc = m_camOps->get_bundle_info(m_camHandle, m_handle, &bundleInfo);
298 if (rc != NO_ERROR) {
299 ALOGE("%s: get_bundle_info failed", __func__);
300 return rc;
301 }
302 if (bundleInfo.num_of_streams > 1) {
303 for (int i = 0; i < bundleInfo.num_of_streams; i++) {
304 QCameraStream *pStream = getStreamByServerID(bundleInfo.stream_ids[i]);
305 if (pStream != NULL) {
306 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) {
307 // Skip metadata for reprocess now because PP module cannot handle meta data
308 // May need furthur discussion if Imaginglib need meta data
309 continue;
310 }
311
312 cam_stream_parm_buffer_t param;
313 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t));
314 param.type = CAM_STREAM_PARAM_TYPE_SET_BUNDLE_INFO;
315 param.bundleInfo = bundleInfo;
316 rc = pStream->setParameter(param);
317 if (rc != NO_ERROR) {
318 ALOGE("%s: stream setParameter for set bundle failed", __func__);
319 return rc;
320 }
321 }
322 }
323 }
324 }
325
326 for (size_t i = 0; i < mStreams.size(); i++) {
327 if ((mStreams[i] != NULL) &&
328 (m_handle == mStreams[i]->getChannelHandle())) {
329 mStreams[i]->start();
330 }
331 }
332 rc = m_camOps->start_channel(m_camHandle, m_handle);
333
334 if (rc != NO_ERROR) {
335 for (size_t i = 0; i < mStreams.size(); i++) {
336 if ((mStreams[i] != NULL) &&
337 (m_handle == mStreams[i]->getChannelHandle())) {
338 mStreams[i]->stop();
339 }
340 }
341 } else {
342 m_bIsActive = true;
343 for (size_t i = 0; i < mStreams.size(); i++) {
344 if (mStreams[i] != NULL) {
345 mStreams[i]->cond_signal();
346 }
347 }
348 }
349
350 return rc;
351 }
352
353 /*===========================================================================
354 * FUNCTION : stop
355 *
356 * DESCRIPTION: stop a channel, which will stop all streams belong to this channel
357 *
358 * PARAMETERS : none
359 *
360 * RETURN : int32_t type of status
361 * NO_ERROR -- success
362 * none-zero failure code
363 *==========================================================================*/
stop()364 int32_t QCameraChannel::stop()
365 {
366 int32_t rc = NO_ERROR;
367 ssize_t linkedIdx = -1;
368
369 if (!m_bIsActive) {
370 return NO_INIT;
371 }
372
373 for (size_t i = 0; i < mStreams.size(); i++) {
374 if (mStreams[i] != NULL) {
375 if (m_handle == mStreams[i]->getChannelHandle()) {
376 mStreams[i]->stop();
377 } else {
378 // Remove linked stream from stream list
379 linkedIdx = (ssize_t)i;
380 }
381 }
382 }
383 if (linkedIdx > 0) {
384 mStreams.removeAt((size_t)linkedIdx);
385 }
386
387 rc = m_camOps->stop_channel(m_camHandle, m_handle);
388
389 m_bIsActive = false;
390 return rc;
391 }
392
393 /*===========================================================================
394 * FUNCTION : bufDone
395 *
396 * DESCRIPTION: return a stream buf back to kernel
397 *
398 * PARAMETERS :
399 * @recvd_frame : stream buf frame to be returned
400 *
401 * RETURN : int32_t type of status
402 * NO_ERROR -- success
403 * none-zero failure code
404 *==========================================================================*/
bufDone(mm_camera_super_buf_t * recvd_frame)405 int32_t QCameraChannel::bufDone(mm_camera_super_buf_t *recvd_frame)
406 {
407 int32_t rc = NO_ERROR;
408 for (uint32_t i = 0; i < recvd_frame->num_bufs; i++) {
409 if (recvd_frame->bufs[i] != NULL) {
410 for (size_t j = 0; j < mStreams.size(); j++) {
411 if (mStreams[j] != NULL &&
412 mStreams[j]->getMyHandle() == recvd_frame->bufs[i]->stream_id) {
413 rc = mStreams[j]->bufDone(recvd_frame->bufs[i]->buf_idx);
414 break; // break loop j
415 }
416 }
417 }
418 }
419
420 return rc;
421 }
422
423 /*===========================================================================
424 * FUNCTION : processZoomDone
425 *
426 * DESCRIPTION: process zoom done event
427 *
428 * PARAMETERS :
429 * @previewWindoe : ptr to preview window ops table, needed to set preview
430 * crop information
431 * @crop_info : crop info as a result of zoom operation
432 *
433 * RETURN : int32_t type of status
434 * NO_ERROR -- success
435 * none-zero failure code
436 *==========================================================================*/
processZoomDone(preview_stream_ops_t * previewWindow,cam_crop_data_t & crop_info)437 int32_t QCameraChannel::processZoomDone(preview_stream_ops_t *previewWindow,
438 cam_crop_data_t &crop_info)
439 {
440 int32_t rc = NO_ERROR;
441 for (size_t i = 0; i < mStreams.size(); i++) {
442 if ((mStreams[i] != NULL) &&
443 (m_handle == mStreams[i]->getChannelHandle())) {
444 rc = mStreams[i]->processZoomDone(previewWindow, crop_info);
445 }
446 }
447 return rc;
448 }
449
450 /*===========================================================================
451 * FUNCTION : getStreamByHandle
452 *
453 * DESCRIPTION: return stream object by stream handle
454 *
455 * PARAMETERS :
456 * @streamHandle : stream handle
457 *
458 * RETURN : stream object. NULL if not found
459 *==========================================================================*/
getStreamByHandle(uint32_t streamHandle)460 QCameraStream *QCameraChannel::getStreamByHandle(uint32_t streamHandle)
461 {
462 for (size_t i = 0; i < mStreams.size(); i++) {
463 if (mStreams[i] != NULL && mStreams[i]->getMyHandle() == streamHandle) {
464 return mStreams[i];
465 }
466 }
467 return NULL;
468 }
469
470 /*===========================================================================
471 * FUNCTION : getStreamByServerID
472 *
473 * DESCRIPTION: return stream object by stream server ID from daemon
474 *
475 * PARAMETERS :
476 * @serverID : stream server ID
477 *
478 * RETURN : stream object. NULL if not found
479 *==========================================================================*/
getStreamByServerID(uint32_t serverID)480 QCameraStream *QCameraChannel::getStreamByServerID(uint32_t serverID)
481 {
482 for (size_t i = 0; i < mStreams.size(); i++) {
483 if (mStreams[i] != NULL && mStreams[i]->getMyServerID() == serverID) {
484 return mStreams[i];
485 }
486 }
487 return NULL;
488 }
489
490 /*===========================================================================
491 * FUNCTION : getStreamByIndex
492 *
493 * DESCRIPTION: return stream object by index of streams in the channel
494 *
495 * PARAMETERS :
496 * @index : index of stream in the channel
497 *
498 * RETURN : stream object. NULL if not found
499 *==========================================================================*/
getStreamByIndex(uint32_t index)500 QCameraStream *QCameraChannel::getStreamByIndex(uint32_t index)
501 {
502 if (index >= MAX_STREAM_NUM_IN_BUNDLE) {
503 return NULL;
504 }
505
506 if (index < mStreams.size()) {
507 return mStreams[index];
508 }
509 return NULL;
510 }
511
512 /*===========================================================================
513 * FUNCTION : UpdateStreamBasedParameters
514 *
515 * DESCRIPTION: update any stream based settings from parameters
516 *
517 * PARAMETERS :
518 * @param : reference to parameters object
519 *
520 * RETURN : int32_t type of status
521 * NO_ERROR -- success
522 * none-zero failure code
523 *==========================================================================*/
UpdateStreamBasedParameters(QCameraParameters & param)524 int32_t QCameraChannel::UpdateStreamBasedParameters(QCameraParameters ¶m)
525 {
526 int32_t rc = NO_ERROR;
527 if (param.isPreviewFlipChanged()) {
528 // try to find preview stream
529 for (size_t i = 0; i < mStreams.size(); i++) {
530 if ((mStreams[i] != NULL) &&
531 (m_handle == mStreams[i]->getChannelHandle()) &&
532 (mStreams[i]->isTypeOf(CAM_STREAM_TYPE_PREVIEW) ||
533 (mStreams[i]->isOrignalTypeOf(CAM_STREAM_TYPE_PREVIEW))) ) {
534 cam_stream_parm_buffer_t param_buf;
535 memset(¶m_buf, 0, sizeof(cam_stream_parm_buffer_t));
536 param_buf.type = CAM_STREAM_PARAM_TYPE_SET_FLIP;
537 param_buf.flipInfo.flip_mask =
538 (uint32_t)param.getFlipMode(CAM_STREAM_TYPE_PREVIEW);
539 rc = mStreams[i]->setParameter(param_buf);
540 if (rc != NO_ERROR) {
541 ALOGE("%s: set preview stream flip failed", __func__);
542 }
543 }
544 }
545 }
546 if (param.isVideoFlipChanged()) {
547 // try to find video stream
548 for (size_t i = 0; i < mStreams.size(); i++) {
549 if ((mStreams[i] != NULL) &&
550 (m_handle == mStreams[i]->getChannelHandle()) &&
551 (mStreams[i]->isTypeOf(CAM_STREAM_TYPE_VIDEO) ||
552 (mStreams[i]->isOrignalTypeOf(CAM_STREAM_TYPE_VIDEO))) ) {
553 cam_stream_parm_buffer_t param_buf;
554 memset(¶m_buf, 0, sizeof(cam_stream_parm_buffer_t));
555 param_buf.type = CAM_STREAM_PARAM_TYPE_SET_FLIP;
556 param_buf.flipInfo.flip_mask =
557 (uint32_t)param.getFlipMode(CAM_STREAM_TYPE_VIDEO);
558 rc = mStreams[i]->setParameter(param_buf);
559 if (rc != NO_ERROR) {
560 ALOGE("%s: set video stream flip failed", __func__);
561 }
562 }
563 }
564 }
565 if (param.isSnapshotFlipChanged()) {
566 // try to find snapshot/postview stream
567 for (size_t i = 0; i < mStreams.size(); i++) {
568 if (mStreams[i] != NULL &&
569 (m_handle == mStreams[i]->getChannelHandle()) &&
570 (mStreams[i]->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT) ||
571 mStreams[i]->isOrignalTypeOf(CAM_STREAM_TYPE_SNAPSHOT) ||
572 mStreams[i]->isTypeOf(CAM_STREAM_TYPE_POSTVIEW) ||
573 mStreams[i]->isOrignalTypeOf(CAM_STREAM_TYPE_POSTVIEW) ) ) {
574 cam_stream_parm_buffer_t param_buf;
575 memset(¶m_buf, 0, sizeof(cam_stream_parm_buffer_t));
576 param_buf.type = CAM_STREAM_PARAM_TYPE_SET_FLIP;
577 param_buf.flipInfo.flip_mask =
578 (uint32_t)param.getFlipMode(CAM_STREAM_TYPE_SNAPSHOT);
579 rc = mStreams[i]->setParameter(param_buf);
580 if (rc != NO_ERROR) {
581 ALOGE("%s: set snapshot stream flip failed", __func__);
582 }
583 }
584 }
585 }
586 return rc;
587 }
588
589 /*===========================================================================
590 * FUNCTION : QCameraPicChannel
591 *
592 * DESCRIPTION: constructor of QCameraPicChannel
593 *
594 * PARAMETERS :
595 * @cam_handle : camera handle
596 * @cam_ops : ptr to camera ops table
597 *
598 * RETURN : none
599 *==========================================================================*/
QCameraPicChannel(uint32_t cam_handle,mm_camera_ops_t * cam_ops)600 QCameraPicChannel::QCameraPicChannel(uint32_t cam_handle,
601 mm_camera_ops_t *cam_ops) :
602 QCameraChannel(cam_handle, cam_ops)
603 {
604 m_bAllowDynBufAlloc = true;
605 }
606
607 /*===========================================================================
608 * FUNCTION : QCameraPicChannel
609 *
610 * DESCRIPTION: default constructor of QCameraPicChannel
611 *
612 * PARAMETERS : none
613 *
614 * RETURN : none
615 *==========================================================================*/
QCameraPicChannel()616 QCameraPicChannel::QCameraPicChannel()
617 {
618 m_bAllowDynBufAlloc = true;
619 }
620
621 /*===========================================================================
622 * FUNCTION : ~QCameraPicChannel
623 *
624 * DESCRIPTION: destructor of QCameraPicChannel
625 *
626 * PARAMETERS : none
627 *
628 * RETURN : none
629 *==========================================================================*/
~QCameraPicChannel()630 QCameraPicChannel::~QCameraPicChannel()
631 {
632 }
633
634 /*===========================================================================
635 * FUNCTION : takePicture
636 *
637 * DESCRIPTION: send request for queued snapshot frames
638 *
639 * PARAMETERS :
640 * @num_of_snapshot : number of snapshot frames requested
641 * @num_of_retro_snapshot : number of retro snapshot frames requested
642 *
643 * RETURN : int32_t type of status
644 * NO_ERROR -- success
645 * none-zero failure code
646 *==========================================================================*/
takePicture(uint8_t num_of_snapshot,uint8_t num_of_retro_snapshot)647 int32_t QCameraPicChannel::takePicture (
648 uint8_t num_of_snapshot,
649 uint8_t num_of_retro_snapshot)
650 {
651 int32_t rc = m_camOps->request_super_buf(m_camHandle,
652 m_handle,
653 num_of_snapshot,
654 num_of_retro_snapshot);
655 return rc;
656 }
657
658 /*===========================================================================
659 * FUNCTION : cancelPicture
660 *
661 * DESCRIPTION: cancel request for queued snapshot frames
662 *
663 * PARAMETERS : none
664 *
665 * RETURN : int32_t type of status
666 * NO_ERROR -- success
667 * none-zero failure code
668 *==========================================================================*/
cancelPicture()669 int32_t QCameraPicChannel::cancelPicture()
670 {
671 int32_t rc = m_camOps->cancel_super_buf_request(m_camHandle, m_handle);
672 return rc;
673 }
674
675 /*===========================================================================
676 * FUNCTION : stopAdvancedCapture
677 *
678 * DESCRIPTION: stop advanced capture based on advanced capture type.
679 *
680 * PARAMETERS :
681 * @type : advanced capture type.
682 *
683 * RETURN : int32_t type of status
684 * NO_ERROR -- success
685 * none-zero failure code
686 *==========================================================================*/
stopAdvancedCapture(mm_camera_advanced_capture_t type)687 int32_t QCameraPicChannel::stopAdvancedCapture(mm_camera_advanced_capture_t type)
688 {
689 int32_t rc = m_camOps->process_advanced_capture(m_camHandle,
690 m_handle, type, 0, NULL);
691 return rc;
692 }
693
694 /*===========================================================================
695 * FUNCTION : startAdvancedCapture
696 *
697 * DESCRIPTION: start advanced capture based on advanced capture type.
698 *
699 * PARAMETERS :
700 * @type : advanced capture type.
701 * @config: advance capture config
702 *
703 * RETURN : int32_t type of status
704 * NO_ERROR -- success
705 * none-zero failure code
706 *==========================================================================*/
startAdvancedCapture(mm_camera_advanced_capture_t type,cam_capture_frame_config_t * config)707 int32_t QCameraPicChannel::startAdvancedCapture(mm_camera_advanced_capture_t type,
708 cam_capture_frame_config_t *config)
709 {
710 int32_t rc = NO_ERROR;
711
712 rc = m_camOps->process_advanced_capture(m_camHandle, m_handle, type,
713 1, config);
714 return rc;
715 }
716
717 /*===========================================================================
718 * FUNCTION : flushSuperbuffer
719 *
720 * DESCRIPTION: flush the all superbuffer frames.
721 *
722 * PARAMETERS :
723 * @frame_idx : frame index of focused frame
724 *
725 * RETURN : int32_t type of status
726 * NO_ERROR -- success
727 * none-zero failure code
728 *==========================================================================*/
flushSuperbuffer(uint32_t frame_idx)729 int32_t QCameraPicChannel::flushSuperbuffer(uint32_t frame_idx)
730 {
731 int32_t rc = m_camOps->flush_super_buf_queue(m_camHandle, m_handle, frame_idx);
732 return rc;
733 }
734
735 /*===========================================================================
736 * FUNCTION : QCameraVideoChannel
737 *
738 * DESCRIPTION: constructor of QCameraVideoChannel
739 *
740 * PARAMETERS :
741 * @cam_handle : camera handle
742 * @cam_ops : ptr to camera ops table
743 *
744 * RETURN : none
745 *==========================================================================*/
QCameraVideoChannel(uint32_t cam_handle,mm_camera_ops_t * cam_ops)746 QCameraVideoChannel::QCameraVideoChannel(uint32_t cam_handle,
747 mm_camera_ops_t *cam_ops) :
748 QCameraChannel(cam_handle, cam_ops)
749 {
750 }
751
752 /*===========================================================================
753 * FUNCTION : QCameraVideoChannel
754 *
755 * DESCRIPTION: default constructor of QCameraVideoChannel
756 *
757 * PARAMETERS : none
758 *
759 * RETURN : none
760 *==========================================================================*/
QCameraVideoChannel()761 QCameraVideoChannel::QCameraVideoChannel()
762 {
763 }
764
765 /*===========================================================================
766 * FUNCTION : ~QCameraVideoChannel
767 *
768 * DESCRIPTION: destructor of QCameraVideoChannel
769 *
770 * PARAMETERS : none
771 *
772 * RETURN : none
773 *==========================================================================*/
~QCameraVideoChannel()774 QCameraVideoChannel::~QCameraVideoChannel()
775 {
776 }
777
778 /*===========================================================================
779 * FUNCTION : releaseFrame
780 *
781 * DESCRIPTION: return video frame from app
782 *
783 * PARAMETERS :
784 * @opaque : ptr to video frame to be returned
785 * @isMetaData : if frame is a metadata or real frame
786 *
787 * RETURN : int32_t type of status
788 * NO_ERROR -- success
789 * none-zero failure code
790 *==========================================================================*/
releaseFrame(const void * opaque,bool isMetaData)791 int32_t QCameraVideoChannel::releaseFrame(const void * opaque, bool isMetaData)
792 {
793 QCameraStream *pVideoStream = NULL;
794 for (size_t i = 0; i < mStreams.size(); i++) {
795 if (mStreams[i] != NULL && mStreams[i]->isTypeOf(CAM_STREAM_TYPE_VIDEO)) {
796 pVideoStream = mStreams[i];
797 break;
798 }
799 }
800
801 if (NULL == pVideoStream) {
802 ALOGE("%s: No video stream in the channel", __func__);
803 return BAD_VALUE;
804 }
805
806 int32_t rc = pVideoStream->bufDone(opaque, isMetaData);
807 return rc;
808 }
809
810 /*===========================================================================
811 * FUNCTION : QCameraReprocessChannel
812 *
813 * DESCRIPTION: constructor of QCameraReprocessChannel
814 *
815 * PARAMETERS :
816 * @cam_handle : camera handle
817 * @cam_ops : ptr to camera ops table
818 * @pp_mask : post-proccess feature mask
819 *
820 * RETURN : none
821 *==========================================================================*/
QCameraReprocessChannel(uint32_t cam_handle,mm_camera_ops_t * cam_ops)822 QCameraReprocessChannel::QCameraReprocessChannel(uint32_t cam_handle,
823 mm_camera_ops_t *cam_ops) :
824 QCameraChannel(cam_handle, cam_ops),
825 m_pSrcChannel(NULL)
826 {
827 memset(mSrcStreamHandles, 0, sizeof(mSrcStreamHandles));
828 }
829
830 /*===========================================================================
831 * FUNCTION : QCameraReprocessChannel
832 *
833 * DESCRIPTION: default constructor of QCameraReprocessChannel
834 *
835 * PARAMETERS : none
836 *
837 * RETURN : none
838 *==========================================================================*/
QCameraReprocessChannel()839 QCameraReprocessChannel::QCameraReprocessChannel() :
840 m_pSrcChannel(NULL)
841 {
842 }
843
844 /*===========================================================================
845 * FUNCTION : ~QCameraReprocessChannel
846 *
847 * DESCRIPTION: destructor of QCameraReprocessChannel
848 *
849 * PARAMETERS : none
850 *
851 * RETURN : none
852 *==========================================================================*/
~QCameraReprocessChannel()853 QCameraReprocessChannel::~QCameraReprocessChannel()
854 {
855 }
856
857 /*===========================================================================
858 * FUNCTION : addReprocStreamsFromSource
859 *
860 * DESCRIPTION: add reprocess streams from input source channel
861 *
862 * PARAMETERS :
863 * @allocator : stream related buffer allocator
864 * @featureConfig : pp feature configuration
865 * @pSrcChannel : ptr to input source channel that needs reprocess
866 * @minStreamBufNum: number of stream buffers needed
867 * @burstNum : number of burst captures needed
868 * @paddingInfo : padding information
869 * @param : reference to parameters
870 * @contStream : continous streaming mode or burst
871 * @offline : configure for offline reprocessing
872 *
873 * RETURN : int32_t type of status
874 * NO_ERROR -- success
875 * none-zero failure code
876 *==========================================================================*/
addReprocStreamsFromSource(QCameraAllocator & allocator,cam_pp_feature_config_t & featureConfig,QCameraChannel * pSrcChannel,uint8_t minStreamBufNum,uint8_t burstNum,cam_padding_info_t * paddingInfo,QCameraParameters & param,bool contStream,bool offline)877 int32_t QCameraReprocessChannel::addReprocStreamsFromSource(
878 QCameraAllocator& allocator, cam_pp_feature_config_t &featureConfig,
879 QCameraChannel *pSrcChannel, uint8_t minStreamBufNum, uint8_t burstNum,
880 cam_padding_info_t *paddingInfo, QCameraParameters ¶m, bool contStream,
881 bool offline)
882 {
883 int32_t rc = 0;
884 QCameraStream *pStream = NULL;
885 QCameraHeapMemory *pStreamInfoBuf = NULL;
886 QCameraHeapMemory *pMiscBuf = NULL;
887 cam_stream_info_t *streamInfo = NULL;
888 cam_padding_info_t padding;
889
890 memset(mSrcStreamHandles, 0, sizeof(mSrcStreamHandles));
891 if (NULL == paddingInfo) {
892 return BAD_VALUE;
893 }
894 padding = *paddingInfo;
895 //Use maximum padding so that the buffer
896 //can be rotated
897 padding.width_padding = MAX(padding.width_padding, padding.height_padding);
898 padding.height_padding = padding.width_padding;
899
900 CDBG("%s : %d: num of src stream = %d", __func__, __LINE__, pSrcChannel->getNumOfStreams());
901
902 for (uint32_t i = 0; i < pSrcChannel->getNumOfStreams(); i++) {
903 pStream = pSrcChannel->getStreamByIndex(i);
904 if (pStream != NULL) {
905 if (param.getofflineRAW() && !pStream->isTypeOf(CAM_STREAM_TYPE_RAW)) {
906 //Skip all the stream other than RAW incase of offline of RAW
907 continue;
908 }
909 if (pStream->isTypeOf(CAM_STREAM_TYPE_RAW) && !param.getofflineRAW()) {
910 // Skip raw for reprocess now because PP module cannot handle
911 // meta data&raw. May need furthur discussion if Imaginglib need meta data
912 continue;
913 }
914
915 if ((pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) ||
916 (pStream->isTypeOf(CAM_STREAM_TYPE_ANALYSIS))) {
917 // Skip metadata
918 continue;
919 }
920
921 if (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW) ||
922 pStream->isTypeOf(CAM_STREAM_TYPE_PREVIEW)) {
923 // Skip postview: in non zsl case, dont want to send
924 // thumbnail through reprocess.
925 // Skip preview: for same reason for zsl case
926 continue;
927 }
928
929 if (pStream->isTypeOf(CAM_STREAM_TYPE_PREVIEW) ||
930 pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW) ||
931 pStream->isOrignalTypeOf(CAM_STREAM_TYPE_PREVIEW) ||
932 pStream->isOrignalTypeOf(CAM_STREAM_TYPE_POSTVIEW) ||
933 (param.getofflineRAW() && pStream->isTypeOf(CAM_STREAM_TYPE_RAW))) {
934 uint32_t feature_mask = featureConfig.feature_mask;
935
936 if ((feature_mask & ~CAM_QCOM_FEATURE_HDR) == 0
937 && param.isHDREnabled()
938 && !param.isHDRThumbnailProcessNeeded()) {
939
940 // Skip thumbnail stream reprocessing in HDR
941 // if only hdr is enabled
942 continue;
943 }
944
945 // skip thumbnail reprocessing if not needed
946 if (!param.needThumbnailReprocess(&feature_mask)) {
947 continue;
948 }
949
950 //Don't do WNR for thumbnail
951 feature_mask &= ~CAM_QCOM_FEATURE_DENOISE2D;
952 if (!feature_mask) {
953 // Skip thumbnail stream reprocessing since no other
954 //reprocessing is enabled.
955 continue;
956 }
957 }
958
959 pStreamInfoBuf = allocator.allocateStreamInfoBuf(CAM_STREAM_TYPE_OFFLINE_PROC);
960 if (pStreamInfoBuf == NULL) {
961 ALOGE("%s: no mem for stream info buf", __func__);
962 rc = NO_MEMORY;
963 break;
964 }
965
966 streamInfo = (cam_stream_info_t *)pStreamInfoBuf->getPtr(0);
967 memset(streamInfo, 0, sizeof(cam_stream_info_t));
968 streamInfo->stream_type = CAM_STREAM_TYPE_OFFLINE_PROC;
969 // Enable CPP high performance mode to put it in turbo frequency mode for
970 // burst/longshot/HDR snapshot cases
971 streamInfo->perf_mode = CAM_PERF_HIGH_PERFORMANCE;
972 if (param.getofflineRAW() && pStream->isTypeOf(CAM_STREAM_TYPE_RAW)) {
973 streamInfo->fmt = CAM_FORMAT_YUV_420_NV21;
974 } else {
975 rc = pStream->getFormat(streamInfo->fmt);
976 }
977 rc = pStream->getFrameDimension(streamInfo->dim);
978 if ( contStream ) {
979 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
980 streamInfo->num_of_burst = 0;
981 } else {
982 streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
983 streamInfo->num_of_burst = burstNum;
984 }
985
986 cam_stream_reproc_config_t rp_cfg;
987 memset(&rp_cfg, 0, sizeof(cam_stream_reproc_config_t));
988 if (offline) {
989 cam_frame_len_offset_t offset;
990 memset(&offset, 0, sizeof(cam_frame_len_offset_t));
991
992 rp_cfg.pp_type = CAM_OFFLINE_REPROCESS_TYPE;
993 pStream->getFormat(rp_cfg.offline.input_fmt);
994 pStream->getFrameDimension(rp_cfg.offline.input_dim);
995 pStream->getFrameOffset(offset);
996 rp_cfg.offline.input_buf_planes.plane_info = offset;
997 rp_cfg.offline.input_type = pStream->getMyOriginalType();
998 //For input metadata + input buffer
999 rp_cfg.offline.num_of_bufs = 2;
1000 } else {
1001 rp_cfg.pp_type = CAM_ONLINE_REPROCESS_TYPE;
1002 rp_cfg.online.input_stream_id = pStream->getMyServerID();
1003 rp_cfg.online.input_stream_type = pStream->getMyOriginalType();
1004 }
1005 param.getStreamRotation(streamInfo->stream_type,
1006 streamInfo->pp_config, streamInfo->dim);
1007 streamInfo->reprocess_config = rp_cfg;
1008 streamInfo->reprocess_config.pp_feature_config = featureConfig;
1009
1010 if (!(pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT) ||
1011 pStream->isOrignalTypeOf(CAM_STREAM_TYPE_SNAPSHOT))) {
1012 streamInfo->reprocess_config.pp_feature_config.feature_mask &= ~CAM_QCOM_FEATURE_CAC;
1013 //Don't do WNR for thumbnail
1014 streamInfo->reprocess_config.pp_feature_config.feature_mask &= ~CAM_QCOM_FEATURE_DENOISE2D;
1015
1016 if (param.isHDREnabled()
1017 && !param.isHDRThumbnailProcessNeeded()){
1018 streamInfo->reprocess_config.pp_feature_config.feature_mask
1019 &= ~CAM_QCOM_FEATURE_HDR;
1020 }
1021 }
1022
1023
1024 if (streamInfo->reprocess_config.online.input_stream_type == CAM_STREAM_TYPE_SNAPSHOT) {
1025 // Reprocess can be for both zsl and non-zsl cases
1026 int flipMode =
1027 param.getFlipMode(streamInfo->reprocess_config.online.input_stream_type);
1028 if (flipMode > 0) {
1029 streamInfo->reprocess_config.pp_feature_config.feature_mask |=
1030 CAM_QCOM_FEATURE_FLIP;
1031 streamInfo->reprocess_config.pp_feature_config.flip = (uint32_t)flipMode;
1032 }
1033 }
1034
1035 if (streamInfo->reprocess_config.offline.input_type == CAM_STREAM_TYPE_SNAPSHOT) {
1036 int flipMode =
1037 param.getFlipMode(streamInfo->reprocess_config.offline.input_type);
1038 if (flipMode > 0) {
1039 streamInfo->reprocess_config.pp_feature_config.feature_mask |=
1040 CAM_QCOM_FEATURE_FLIP;
1041 streamInfo->reprocess_config.pp_feature_config.flip = (uint32_t)flipMode;
1042 }
1043 }
1044
1045 if ((streamInfo->reprocess_config.pp_feature_config.feature_mask
1046 & CAM_QCOM_FEATURE_SCALE)
1047 && param.m_reprocScaleParam.isScaleEnabled()
1048 && param.m_reprocScaleParam.isUnderScaling()) {
1049 //we only Scale Snapshot frame
1050 if (pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT)) {
1051 streamInfo->dim.width =
1052 streamInfo->reprocess_config.pp_feature_config.scale_param.output_width;
1053 streamInfo->dim.height =
1054 streamInfo->reprocess_config.pp_feature_config.scale_param.output_height;
1055 }
1056 CDBG_HIGH("%s: stream width=%d, height=%d.",
1057 __func__, streamInfo->dim.width, streamInfo->dim.height);
1058 }
1059
1060 // save source stream handler
1061 mSrcStreamHandles[mStreams.size()] = pStream->getMyHandle();
1062
1063 pMiscBuf = allocator.allocateMiscBuf(streamInfo);
1064
1065 // add reprocess stream
1066 rc = addStream(allocator, pStreamInfoBuf, pMiscBuf,
1067 minStreamBufNum, &padding, NULL, NULL, false, false,
1068 streamInfo->reprocess_config.pp_feature_config.rotation);
1069 if (rc != NO_ERROR) {
1070 ALOGE("%s: add reprocess stream failed, ret = %d", __func__, rc);
1071 break;
1072 }
1073 }
1074 }
1075
1076 if (rc == NO_ERROR) {
1077 m_pSrcChannel = pSrcChannel;
1078 }
1079 return rc;
1080 }
1081
1082 /*===========================================================================
1083 * FUNCTION : getStreamBySrouceHandle
1084 *
1085 * DESCRIPTION: find reprocess stream by its source stream handle
1086 *
1087 * PARAMETERS :
1088 * @srcHandle : source stream handle
1089 *
1090 * RETURN : ptr to reprocess stream if found. NULL if not found
1091 *==========================================================================*/
getStreamBySrouceHandle(uint32_t srcHandle)1092 QCameraStream * QCameraReprocessChannel::getStreamBySrouceHandle(uint32_t srcHandle)
1093 {
1094 QCameraStream *pStream = NULL;
1095
1096 for (size_t i = 0; i < mStreams.size(); i++) {
1097 if (mSrcStreamHandles[i] == srcHandle) {
1098 pStream = mStreams[i];
1099 break;
1100 }
1101 }
1102
1103 return pStream;
1104 }
1105
1106 /*===========================================================================
1107 * FUNCTION : stop
1108 *
1109 * DESCRIPTION: Unmap offline buffers and stop channel
1110 *
1111 * PARAMETERS : none
1112 *
1113 * RETURN : int32_t type of status
1114 * NO_ERROR -- success
1115 * none-zero failure code
1116 *==========================================================================*/
stop()1117 int32_t QCameraReprocessChannel::stop()
1118 {
1119 if (!mOfflineBuffers.empty()) {
1120 QCameraStream *stream = NULL;
1121 List<OfflineBuffer>::iterator it = mOfflineBuffers.begin();
1122 int error = NO_ERROR;
1123 for( ; it != mOfflineBuffers.end(); it++) {
1124 stream = (*it).stream;
1125 if (NULL != stream) {
1126 error = stream->unmapBuf((*it).type,
1127 (*it).index,
1128 -1);
1129 if (NO_ERROR != error) {
1130 ALOGE("%s: Error during offline buffer unmap %d",
1131 __func__, error);
1132 }
1133 }
1134 }
1135 mOfflineBuffers.clear();
1136 }
1137
1138 return QCameraChannel::stop();
1139 }
1140
1141 /*===========================================================================
1142 * FUNCTION : doReprocessOffline
1143 *
1144 * DESCRIPTION: request to do offline reprocess on the frame
1145 *
1146 * PARAMETERS :
1147 * @frame : frame to be performed a reprocess
1148 * @meta_buf : Metadata buffer for reprocessing
1149 *
1150 * RETURN : int32_t type of status
1151 * NO_ERROR -- success
1152 * none-zero failure code
1153 *==========================================================================*/
doReprocessOffline(mm_camera_super_buf_t * frame,mm_camera_buf_def_t * meta_buf)1154 int32_t QCameraReprocessChannel::doReprocessOffline(mm_camera_super_buf_t *frame,
1155 mm_camera_buf_def_t *meta_buf)
1156 {
1157 int32_t rc = 0;
1158 OfflineBuffer mappedBuffer;
1159 QCameraStream *pStream = NULL;
1160
1161 if (mStreams.size() < 1) {
1162 ALOGE("%s: No reprocess streams", __func__);
1163 return -1;
1164 }
1165 if (m_pSrcChannel == NULL) {
1166 ALOGE("%s: No source channel for reprocess", __func__);
1167 return -1;
1168 }
1169
1170 if (frame == NULL) {
1171 ALOGE("%s: Invalid source frame", __func__);
1172 return BAD_VALUE;
1173 }
1174
1175 for (uint32_t i = 0; i < frame->num_bufs; i++) {
1176 pStream = getStreamBySrouceHandle(frame->bufs[i]->stream_id);
1177 if ((pStream != NULL) &&
1178 (m_handle == pStream->getChannelHandle())) {
1179 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) {
1180 continue;
1181 }
1182
1183 uint32_t meta_buf_index = 0;
1184 if (NULL != meta_buf) {
1185 rc = pStream->mapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_META_BUF,
1186 meta_buf_index,
1187 -1,
1188 meta_buf->fd,
1189 meta_buf->frame_len);
1190 if (NO_ERROR != rc ) {
1191 ALOGE("%s : Error during metadata buffer mapping",
1192 __func__);
1193 break;
1194 }
1195 // we have meta data sent together with reprocess frame
1196 uint32_t stream_id = frame->bufs[i]->stream_id;
1197 QCameraStream *srcStream =
1198 m_pSrcChannel->getStreamByHandle(stream_id);
1199 metadata_buffer_t *pMetaData =
1200 (metadata_buffer_t *)meta_buf->buffer;
1201 if ((NULL != pMetaData) && (NULL != srcStream)) {
1202 IF_META_AVAILABLE(cam_crop_data_t, crop, CAM_INTF_META_CROP_DATA, pMetaData) {
1203 if (MAX_NUM_STREAMS > crop->num_of_streams) {
1204 for (int j = 0; j < MAX_NUM_STREAMS; j++) {
1205 if (crop->crop_info[j].stream_id ==
1206 srcStream->getMyServerID()) {
1207 // Store crop/roi information for offline reprocess
1208 // in the reprocess stream slot
1209 crop->crop_info[crop->num_of_streams].crop =
1210 crop->crop_info[j].crop;
1211 crop->crop_info[crop->num_of_streams].roi_map =
1212 crop->crop_info[j].roi_map;
1213 crop->crop_info[crop->num_of_streams].stream_id =
1214 mStreams[0]->getMyServerID();
1215 crop->num_of_streams++;
1216
1217 break;
1218 }
1219 }
1220 } else {
1221 ALOGE("%s: No space to add reprocess stream crop/roi information",
1222 __func__);
1223 }
1224 }
1225 }
1226 }
1227 mappedBuffer.index = meta_buf_index;
1228 mappedBuffer.stream = pStream;
1229 mappedBuffer.type = CAM_MAPPING_BUF_TYPE_OFFLINE_META_BUF;
1230 mOfflineBuffers.push_back(mappedBuffer);
1231
1232 uint32_t buf_index = 1;
1233 rc = pStream->mapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF,
1234 buf_index,
1235 -1,
1236 frame->bufs[i]->fd,
1237 frame->bufs[i]->frame_len);
1238 if (NO_ERROR != rc ) {
1239 ALOGE("%s : Error during reprocess input buffer mapping",
1240 __func__);
1241 break;
1242 }
1243 mappedBuffer.index = buf_index;
1244 mappedBuffer.stream = pStream;
1245 mappedBuffer.type = CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF;
1246 mOfflineBuffers.push_back(mappedBuffer);
1247
1248 cam_stream_parm_buffer_t param;
1249 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t));
1250
1251 param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS;
1252 param.reprocess.buf_index = buf_index;
1253 param.reprocess.frame_idx = frame->bufs[i]->frame_idx;
1254 param.reprocess.meta_present = 1;
1255 param.reprocess.meta_buf_index = meta_buf_index;
1256
1257 rc = pStream->setParameter(param);
1258 if (rc != NO_ERROR) {
1259 ALOGE("%s: stream setParameter for reprocess failed",
1260 __func__);
1261 break;
1262 }
1263 }
1264 }
1265 return rc;
1266 }
1267
1268 /*===========================================================================
1269 * FUNCTION : doReprocess
1270 *
1271 * DESCRIPTION: request to do a reprocess on the frame
1272 *
1273 * PARAMETERS :
1274 * @frame : frame to be performed a reprocess
1275 * @mParameter : camera parameters
1276 * @pMetaStream: Metadata stream handle
1277 * @meta_buf_index : Metadata buffer index
1278 *
1279 * RETURN : int32_t type of status
1280 * NO_ERROR -- success
1281 * none-zero failure code
1282 *==========================================================================*/
doReprocess(mm_camera_super_buf_t * frame,QCameraParameters & mParameter,QCameraStream * pMetaStream,uint8_t meta_buf_index)1283 int32_t QCameraReprocessChannel::doReprocess(mm_camera_super_buf_t *frame,
1284 QCameraParameters &mParameter, QCameraStream *pMetaStream,
1285 uint8_t meta_buf_index)
1286 {
1287 int32_t rc = 0;
1288 if (mStreams.size() < 1) {
1289 ALOGE("%s: No reprocess streams", __func__);
1290 return -1;
1291 }
1292 if (m_pSrcChannel == NULL) {
1293 ALOGE("%s: No source channel for reprocess", __func__);
1294 return -1;
1295 }
1296
1297 for (uint32_t i = 0; i < frame->num_bufs; i++) {
1298 QCameraStream *pStream = getStreamBySrouceHandle(frame->bufs[i]->stream_id);
1299 if ((pStream != NULL) && (m_handle == pStream->getChannelHandle())) {
1300 if (mParameter.getofflineRAW() &&
1301 !pStream->isOrignalTypeOf(CAM_STREAM_TYPE_RAW)) {
1302 continue;
1303 }
1304 if ((pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) ||
1305 (pStream->isTypeOf(CAM_STREAM_TYPE_ANALYSIS))) {
1306 // Skip metadata for reprocess now because PP module cannot handle meta data
1307 // May need furthur discussion if Imaginglib need meta data
1308 continue;
1309 }
1310
1311 if (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW) ||
1312 pStream->isTypeOf(CAM_STREAM_TYPE_PREVIEW)) {
1313 // Skip postview: In non zsl case, dont want to send
1314 // thumbnail through reprocess.
1315 // Skip preview: for same reason in ZSL case
1316 continue;
1317 }
1318
1319 cam_stream_parm_buffer_t param;
1320 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t));
1321 param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS;
1322 param.reprocess.buf_index = frame->bufs[i]->buf_idx;
1323 param.reprocess.frame_idx = frame->bufs[i]->frame_idx;
1324 if (pMetaStream != NULL) {
1325 // we have meta data frame bundled, sent together with reprocess frame
1326 param.reprocess.meta_present = 1;
1327 param.reprocess.meta_stream_handle = pMetaStream->getMyServerID();
1328 param.reprocess.meta_buf_index = meta_buf_index;
1329 }
1330
1331 CDBG_HIGH("Frame for reprocessing id = %d buf Id = %d meta index = %d",
1332 param.reprocess.frame_idx, param.reprocess.buf_index,
1333 param.reprocess.meta_buf_index);
1334
1335 rc = pStream->setParameter(param);
1336 if (rc != NO_ERROR) {
1337 ALOGE("%s: stream setParameter for reprocess failed", __func__);
1338 break;
1339 }
1340 }
1341 }
1342 return rc;
1343 }
1344
1345 /*===========================================================================
1346 * FUNCTION : doReprocess
1347 *
1348 * DESCRIPTION: request to do a reprocess on the frame
1349 *
1350 * PARAMETERS :
1351 * @buf_fd : fd to the input buffer that needs reprocess
1352 * @buf_lenght : length of the input buffer
1353 * @ret_val : result of reprocess.
1354 * Example: Could be faceID in case of register face image.
1355 *
1356 * RETURN : int32_t type of status
1357 * NO_ERROR -- success
1358 * none-zero failure code
1359 *==========================================================================*/
doReprocess(int buf_fd,size_t buf_length,int32_t & ret_val)1360 int32_t QCameraReprocessChannel::doReprocess(int buf_fd,
1361 size_t buf_length, int32_t &ret_val)
1362 {
1363 int32_t rc = 0;
1364 if (mStreams.size() < 1) {
1365 ALOGE("%s: No reprocess streams", __func__);
1366 return -1;
1367 }
1368
1369 uint32_t buf_idx = 0;
1370 for (size_t i = 0; i < mStreams.size(); i++) {
1371 if ((mStreams[i] != NULL) &&
1372 (m_handle != mStreams[i]->getChannelHandle())) {
1373 continue;
1374 }
1375 rc = mStreams[i]->mapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF,
1376 buf_idx, -1,
1377 buf_fd, buf_length);
1378
1379 if (rc == NO_ERROR) {
1380 cam_stream_parm_buffer_t param;
1381 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t));
1382 param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS;
1383 param.reprocess.buf_index = buf_idx;
1384 rc = mStreams[i]->setParameter(param);
1385 if (rc == NO_ERROR) {
1386 ret_val = param.reprocess.ret_val;
1387 }
1388 mStreams[i]->unmapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF,
1389 buf_idx, -1);
1390 }
1391 }
1392 return rc;
1393 }
1394
1395 }; // namespace qcamera
1396