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