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