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(m_bIsActive) {
300 LOGW("Attempt to start active channel");
301 return rc;
302 }
303 if (mStreams.size() > 1) {
304 // there is more than one stream in the channel
305 // we need to notify mctl that all streams in this channel need to be bundled
306 cam_bundle_config_t bundleInfo;
307 memset(&bundleInfo, 0, sizeof(bundleInfo));
308 rc = m_camOps->get_bundle_info(m_camHandle, m_handle, &bundleInfo);
309 if (rc != NO_ERROR) {
310 LOGE("get_bundle_info failed");
311 return rc;
312 }
313 if (bundleInfo.num_of_streams > 1) {
314 for (int i = 0; i < bundleInfo.num_of_streams; i++) {
315 QCameraStream *pStream = getStreamByServerID(bundleInfo.stream_ids[i]);
316 if (pStream != NULL) {
317 if ((pStream->isTypeOf(CAM_STREAM_TYPE_METADATA))
318 || (pStream->isTypeOf(CAM_STREAM_TYPE_OFFLINE_PROC))) {
319 // Skip metadata for reprocess now because PP module cannot handle meta data
320 // May need furthur discussion if Imaginglib need meta data
321 continue;
322 }
323
324 cam_stream_parm_buffer_t param;
325 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t));
326 param.type = CAM_STREAM_PARAM_TYPE_SET_BUNDLE_INFO;
327 param.bundleInfo = bundleInfo;
328 rc = pStream->setParameter(param);
329 if (rc != NO_ERROR) {
330 LOGE("stream setParameter for set bundle failed");
331 return rc;
332 }
333 }
334 }
335 }
336 }
337
338 for (size_t i = 0; i < mStreams.size(); i++) {
339 if ((mStreams[i] != NULL) &&
340 (m_handle == mStreams[i]->getChannelHandle())) {
341 mStreams[i]->start();
342 }
343 }
344 rc = m_camOps->start_channel(m_camHandle, m_handle);
345
346 if (rc != NO_ERROR) {
347 for (size_t i = 0; i < mStreams.size(); i++) {
348 if ((mStreams[i] != NULL) &&
349 (m_handle == mStreams[i]->getChannelHandle())) {
350 mStreams[i]->stop();
351 }
352 }
353 } else {
354 m_bIsActive = true;
355 for (size_t i = 0; i < mStreams.size(); i++) {
356 if (mStreams[i] != NULL) {
357 mStreams[i]->cond_signal();
358 }
359 }
360 }
361
362 return rc;
363 }
364
365 /*===========================================================================
366 * FUNCTION : stop
367 *
368 * DESCRIPTION: stop a channel, which will stop all streams belong to this channel
369 *
370 * PARAMETERS : none
371 *
372 * RETURN : int32_t type of status
373 * NO_ERROR -- success
374 * none-zero failure code
375 *==========================================================================*/
stop()376 int32_t QCameraChannel::stop()
377 {
378 int32_t rc = NO_ERROR;
379 size_t i = 0;
380
381 if (!m_bIsActive) {
382 return NO_INIT;
383 }
384
385 while(i < mStreams.size()) {
386 if (mStreams[i] != NULL) {
387 if (m_handle == mStreams[i]->getChannelHandle()) {
388 mStreams[i]->stop();
389 i++;
390 } else {
391 // Remove linked stream from stream list
392 mStreams.removeAt(i);
393 }
394 }
395 }
396
397 rc = m_camOps->stop_channel(m_camHandle, m_handle);
398
399 m_bIsActive = false;
400 return rc;
401 }
402
403 /*===========================================================================
404 * FUNCTION : bufDone
405 *
406 * DESCRIPTION: return a stream buf back to kernel
407 *
408 * PARAMETERS :
409 * @recvd_frame : stream buf frame to be returned
410 *
411 * RETURN : int32_t type of status
412 * NO_ERROR -- success
413 * none-zero failure code
414 *==========================================================================*/
bufDone(mm_camera_super_buf_t * recvd_frame)415 int32_t QCameraChannel::bufDone(mm_camera_super_buf_t *recvd_frame)
416 {
417 int32_t rc = NO_ERROR;
418 for (uint32_t i = 0; i < recvd_frame->num_bufs; i++) {
419 if (recvd_frame->bufs[i] != NULL) {
420 for (size_t j = 0; j < mStreams.size(); j++) {
421 if (mStreams[j] != NULL &&
422 mStreams[j]->getMyHandle() == recvd_frame->bufs[i]->stream_id) {
423 rc = mStreams[j]->bufDone(recvd_frame->bufs[i]->buf_idx);
424 break; // break loop j
425 }
426 }
427 }
428 }
429
430 return rc;
431 }
432
433 /*===========================================================================
434 * FUNCTION : bufDone
435 *
436 * DESCRIPTION: return specified buffer from super buffer to kernel
437 *
438 * PARAMETERS :
439 * @recvd_frame : stream buf frame to be returned
440 * @stream_id : stream ID of the buffer to be released
441 *
442 * RETURN : int32_t type of status
443 * NO_ERROR -- success
444 * none-zero failure code
445 *==========================================================================*/
bufDone(mm_camera_super_buf_t * recvd_frame,uint32_t stream_id)446 int32_t QCameraChannel::bufDone(mm_camera_super_buf_t *recvd_frame, uint32_t stream_id)
447 {
448 int32_t rc = NO_ERROR;
449 int32_t index;
450 for (int32_t i = 0; i < (int32_t)recvd_frame->num_bufs; i++) {
451 index = -1;
452 if ((recvd_frame->bufs[i] != NULL) &&
453 (recvd_frame->bufs[i]->stream_id == stream_id)) {
454 for (size_t j = 0; j < mStreams.size(); j++) {
455 if ((mStreams[j] != NULL) &&
456 (mStreams[j]->getMyHandle() == stream_id)) {
457 rc = mStreams[j]->bufDone(recvd_frame->bufs[i]->buf_idx);
458 index = i;
459 break; // break loop j
460 }
461 }
462 if ((index >= 0) && (index < (int32_t)recvd_frame->num_bufs)) {
463 for (int32_t j = index; j < (int32_t)(recvd_frame->num_bufs - 1); j++) {
464 recvd_frame->bufs[j] = recvd_frame->bufs[j + 1];
465 }
466 recvd_frame->num_bufs--;
467 i--;
468 }
469 }
470 }
471
472 return rc;
473 }
474
475 /*===========================================================================
476 * FUNCTION : processZoomDone
477 *
478 * DESCRIPTION: process zoom done event
479 *
480 * PARAMETERS :
481 * @previewWindoe : ptr to preview window ops table, needed to set preview
482 * crop information
483 * @crop_info : crop info as a result of zoom operation
484 *
485 * RETURN : int32_t type of status
486 * NO_ERROR -- success
487 * none-zero failure code
488 *==========================================================================*/
processZoomDone(preview_stream_ops_t * previewWindow,cam_crop_data_t & crop_info)489 int32_t QCameraChannel::processZoomDone(preview_stream_ops_t *previewWindow,
490 cam_crop_data_t &crop_info)
491 {
492 int32_t rc = NO_ERROR;
493 for (size_t i = 0; i < mStreams.size(); i++) {
494 if ((mStreams[i] != NULL) &&
495 (m_handle == mStreams[i]->getChannelHandle())) {
496 rc = mStreams[i]->processZoomDone(previewWindow, crop_info);
497 }
498 }
499 return rc;
500 }
501
502 /*===========================================================================
503 * FUNCTION : getStreamByHandle
504 *
505 * DESCRIPTION: return stream object by stream handle
506 *
507 * PARAMETERS :
508 * @streamHandle : stream handle
509 *
510 * RETURN : stream object. NULL if not found
511 *==========================================================================*/
getStreamByHandle(uint32_t streamHandle)512 QCameraStream *QCameraChannel::getStreamByHandle(uint32_t streamHandle)
513 {
514 for (size_t i = 0; i < mStreams.size(); i++) {
515 if (mStreams[i] != NULL && mStreams[i]->getMyHandle() == streamHandle) {
516 return mStreams[i];
517 }
518 }
519 return NULL;
520 }
521
522 /*===========================================================================
523 * FUNCTION : getStreamByServerID
524 *
525 * DESCRIPTION: return stream object by stream server ID from daemon
526 *
527 * PARAMETERS :
528 * @serverID : stream server ID
529 *
530 * RETURN : stream object. NULL if not found
531 *==========================================================================*/
getStreamByServerID(uint32_t serverID)532 QCameraStream *QCameraChannel::getStreamByServerID(uint32_t serverID)
533 {
534 for (size_t i = 0; i < mStreams.size(); i++) {
535 if (mStreams[i] != NULL && mStreams[i]->getMyServerID() == serverID) {
536 return mStreams[i];
537 }
538 }
539 return NULL;
540 }
541
542 /*===========================================================================
543 * FUNCTION : getStreamByIndex
544 *
545 * DESCRIPTION: return stream object by index of streams in the channel
546 *
547 * PARAMETERS :
548 * @index : index of stream in the channel
549 *
550 * RETURN : stream object. NULL if not found
551 *==========================================================================*/
getStreamByIndex(uint32_t index)552 QCameraStream *QCameraChannel::getStreamByIndex(uint32_t index)
553 {
554 if (index >= MAX_STREAM_NUM_IN_BUNDLE) {
555 return NULL;
556 }
557
558 if (index < mStreams.size()) {
559 return mStreams[index];
560 }
561 return NULL;
562 }
563
564 /*===========================================================================
565 * FUNCTION : UpdateStreamBasedParameters
566 *
567 * DESCRIPTION: update any stream based settings from parameters
568 *
569 * PARAMETERS :
570 * @param : reference to parameters object
571 *
572 * RETURN : int32_t type of status
573 * NO_ERROR -- success
574 * none-zero failure code
575 *==========================================================================*/
UpdateStreamBasedParameters(QCameraParametersIntf & param)576 int32_t QCameraChannel::UpdateStreamBasedParameters(QCameraParametersIntf ¶m)
577 {
578 int32_t rc = NO_ERROR;
579 if (param.isPreviewFlipChanged()) {
580 // try to find preview stream
581 for (size_t i = 0; i < mStreams.size(); i++) {
582 if ((mStreams[i] != NULL) &&
583 (m_handle == mStreams[i]->getChannelHandle()) &&
584 (mStreams[i]->isTypeOf(CAM_STREAM_TYPE_PREVIEW) ||
585 (mStreams[i]->isOrignalTypeOf(CAM_STREAM_TYPE_PREVIEW))) ) {
586 cam_stream_parm_buffer_t param_buf;
587 memset(¶m_buf, 0, sizeof(cam_stream_parm_buffer_t));
588 param_buf.type = CAM_STREAM_PARAM_TYPE_SET_FLIP;
589 param_buf.flipInfo.flip_mask =
590 (uint32_t)param.getFlipMode(CAM_STREAM_TYPE_PREVIEW);
591 rc = mStreams[i]->setParameter(param_buf);
592 if (rc != NO_ERROR) {
593 LOGW("set preview stream flip failed");
594 }
595 }
596 }
597 }
598 if (param.isVideoFlipChanged()) {
599 // try to find video stream
600 for (size_t i = 0; i < mStreams.size(); i++) {
601 if ((mStreams[i] != NULL) &&
602 (m_handle == mStreams[i]->getChannelHandle()) &&
603 (mStreams[i]->isTypeOf(CAM_STREAM_TYPE_VIDEO) ||
604 (mStreams[i]->isOrignalTypeOf(CAM_STREAM_TYPE_VIDEO))) ) {
605 cam_stream_parm_buffer_t param_buf;
606 memset(¶m_buf, 0, sizeof(cam_stream_parm_buffer_t));
607 param_buf.type = CAM_STREAM_PARAM_TYPE_SET_FLIP;
608 param_buf.flipInfo.flip_mask =
609 (uint32_t)param.getFlipMode(CAM_STREAM_TYPE_VIDEO);
610 rc = mStreams[i]->setParameter(param_buf);
611 if (rc != NO_ERROR) {
612 LOGW("set video stream flip failed");
613 }
614 }
615 }
616 }
617 if (param.isSnapshotFlipChanged()) {
618 // try to find snapshot/postview stream
619 for (size_t i = 0; i < mStreams.size(); i++) {
620 if (mStreams[i] != NULL &&
621 (m_handle == mStreams[i]->getChannelHandle()) &&
622 (mStreams[i]->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT) ||
623 mStreams[i]->isOrignalTypeOf(CAM_STREAM_TYPE_SNAPSHOT) ||
624 mStreams[i]->isTypeOf(CAM_STREAM_TYPE_POSTVIEW) ||
625 mStreams[i]->isOrignalTypeOf(CAM_STREAM_TYPE_POSTVIEW) ) ) {
626 cam_stream_parm_buffer_t param_buf;
627 memset(¶m_buf, 0, sizeof(cam_stream_parm_buffer_t));
628 param_buf.type = CAM_STREAM_PARAM_TYPE_SET_FLIP;
629 param_buf.flipInfo.flip_mask =
630 (uint32_t)param.getFlipMode(CAM_STREAM_TYPE_SNAPSHOT);
631 rc = mStreams[i]->setParameter(param_buf);
632 if (rc != NO_ERROR) {
633 LOGW("set snapshot stream flip failed");
634 }
635 }
636 }
637 }
638 return rc;
639 }
640
641 /*===========================================================================
642 * FUNCTION : QCameraPicChannel
643 *
644 * DESCRIPTION: constructor of QCameraPicChannel
645 *
646 * PARAMETERS :
647 * @cam_handle : camera handle
648 * @cam_ops : ptr to camera ops table
649 *
650 * RETURN : none
651 *==========================================================================*/
QCameraPicChannel(uint32_t cam_handle,mm_camera_ops_t * cam_ops)652 QCameraPicChannel::QCameraPicChannel(uint32_t cam_handle,
653 mm_camera_ops_t *cam_ops) :
654 QCameraChannel(cam_handle, cam_ops)
655 {
656 m_bAllowDynBufAlloc = true;
657 }
658
659 /*===========================================================================
660 * FUNCTION : QCameraPicChannel
661 *
662 * DESCRIPTION: default constructor of QCameraPicChannel
663 *
664 * PARAMETERS : none
665 *
666 * RETURN : none
667 *==========================================================================*/
QCameraPicChannel()668 QCameraPicChannel::QCameraPicChannel()
669 {
670 m_bAllowDynBufAlloc = true;
671 }
672
673 /*===========================================================================
674 * FUNCTION : ~QCameraPicChannel
675 *
676 * DESCRIPTION: destructor of QCameraPicChannel
677 *
678 * PARAMETERS : none
679 *
680 * RETURN : none
681 *==========================================================================*/
~QCameraPicChannel()682 QCameraPicChannel::~QCameraPicChannel()
683 {
684 }
685
686 /*===========================================================================
687 * FUNCTION : takePicture
688 *
689 * DESCRIPTION: send request for queued snapshot frames
690 *
691 * PARAMETERS :
692 * @buf : request buf info
693 *
694 * RETURN : int32_t type of status
695 * NO_ERROR -- success
696 * none-zero failure code
697 *==========================================================================*/
takePicture(mm_camera_req_buf_t * buf)698 int32_t QCameraPicChannel::takePicture (mm_camera_req_buf_t *buf)
699 {
700 int32_t rc = m_camOps->request_super_buf(m_camHandle, m_handle, buf);
701 return rc;
702 }
703
704 /*===========================================================================
705 * FUNCTION : cancelPicture
706 *
707 * DESCRIPTION: cancel request for queued snapshot frames
708 *
709 * PARAMETERS : none
710 *
711 * RETURN : int32_t type of status
712 * NO_ERROR -- success
713 * none-zero failure code
714 *==========================================================================*/
cancelPicture()715 int32_t QCameraPicChannel::cancelPicture()
716 {
717 int32_t rc = m_camOps->cancel_super_buf_request(m_camHandle, m_handle);
718 return rc;
719 }
720
721 /*===========================================================================
722 * FUNCTION : stopAdvancedCapture
723 *
724 * DESCRIPTION: stop advanced capture based on advanced capture type.
725 *
726 * PARAMETERS :
727 * @type : advanced capture type.
728 *
729 * RETURN : int32_t type of status
730 * NO_ERROR -- success
731 * none-zero failure code
732 *==========================================================================*/
stopAdvancedCapture(mm_camera_advanced_capture_t type)733 int32_t QCameraPicChannel::stopAdvancedCapture(mm_camera_advanced_capture_t type)
734 {
735 int32_t rc = m_camOps->process_advanced_capture(m_camHandle,
736 m_handle, type, 0, NULL);
737 return rc;
738 }
739
740 /*===========================================================================
741 * FUNCTION : startAdvancedCapture
742 *
743 * DESCRIPTION: start advanced capture based on advanced capture type.
744 *
745 * PARAMETERS :
746 * @type : advanced capture type.
747 * @config: advance capture config
748 *
749 * RETURN : int32_t type of status
750 * NO_ERROR -- success
751 * none-zero failure code
752 *==========================================================================*/
startAdvancedCapture(mm_camera_advanced_capture_t type,cam_capture_frame_config_t * config)753 int32_t QCameraPicChannel::startAdvancedCapture(mm_camera_advanced_capture_t type,
754 cam_capture_frame_config_t *config)
755 {
756 int32_t rc = NO_ERROR;
757
758 rc = m_camOps->process_advanced_capture(m_camHandle, m_handle, type,
759 1, config);
760 return rc;
761 }
762
763 /*===========================================================================
764 * FUNCTION : flushSuperbuffer
765 *
766 * DESCRIPTION: flush the all superbuffer frames.
767 *
768 * PARAMETERS :
769 * @frame_idx : frame index of focused frame
770 *
771 * RETURN : int32_t type of status
772 * NO_ERROR -- success
773 * none-zero failure code
774 *==========================================================================*/
flushSuperbuffer(uint32_t frame_idx)775 int32_t QCameraPicChannel::flushSuperbuffer(uint32_t frame_idx)
776 {
777 int32_t rc = m_camOps->flush_super_buf_queue(m_camHandle, m_handle, frame_idx);
778 return rc;
779 }
780
781 /*===========================================================================
782 * FUNCTION : QCameraVideoChannel
783 *
784 * DESCRIPTION: constructor of QCameraVideoChannel
785 *
786 * PARAMETERS :
787 * @cam_handle : camera handle
788 * @cam_ops : ptr to camera ops table
789 *
790 * RETURN : none
791 *==========================================================================*/
QCameraVideoChannel(uint32_t cam_handle,mm_camera_ops_t * cam_ops)792 QCameraVideoChannel::QCameraVideoChannel(uint32_t cam_handle,
793 mm_camera_ops_t *cam_ops) :
794 QCameraChannel(cam_handle, cam_ops)
795 {
796 }
797
798 /*===========================================================================
799 * FUNCTION : QCameraVideoChannel
800 *
801 * DESCRIPTION: default constructor of QCameraVideoChannel
802 *
803 * PARAMETERS : none
804 *
805 * RETURN : none
806 *==========================================================================*/
QCameraVideoChannel()807 QCameraVideoChannel::QCameraVideoChannel()
808 {
809 }
810
811 /*===========================================================================
812 * FUNCTION : ~QCameraVideoChannel
813 *
814 * DESCRIPTION: destructor of QCameraVideoChannel
815 *
816 * PARAMETERS : none
817 *
818 * RETURN : none
819 *==========================================================================*/
~QCameraVideoChannel()820 QCameraVideoChannel::~QCameraVideoChannel()
821 {
822 }
823
824 /*===========================================================================
825 * FUNCTION : takePicture
826 *
827 * DESCRIPTION: send request for queued snapshot frames
828 *
829 * PARAMETERS :
830 * @mm_camera_req_buf_t : request buf info
831 *
832 * RETURN : int32_t type of status
833 * NO_ERROR -- success
834 * none-zero failure code
835 *==========================================================================*/
takePicture(mm_camera_req_buf_t * buf)836 int32_t QCameraVideoChannel::takePicture(mm_camera_req_buf_t *buf)
837 {
838 int32_t rc = m_camOps->request_super_buf(m_camHandle, m_handle, buf);
839 return rc;
840 }
841
842 /*===========================================================================
843 * FUNCTION : cancelPicture
844 *
845 * DESCRIPTION: cancel request for queued snapshot frames
846 *
847 * PARAMETERS : none
848 *
849 * RETURN : int32_t type of status
850 * NO_ERROR -- success
851 * none-zero failure code
852 *==========================================================================*/
cancelPicture()853 int32_t QCameraVideoChannel::cancelPicture()
854 {
855 int32_t rc = m_camOps->cancel_super_buf_request(m_camHandle, m_handle);
856 return rc;
857 }
858
859 /*===========================================================================
860 * FUNCTION : releaseFrame
861 *
862 * DESCRIPTION: return video frame from app
863 *
864 * PARAMETERS :
865 * @opaque : ptr to video frame to be returned
866 * @isMetaData : if frame is a metadata or real frame
867 *
868 * RETURN : int32_t type of status
869 * NO_ERROR -- success
870 * none-zero failure code
871 *==========================================================================*/
releaseFrame(const void * opaque,bool isMetaData)872 int32_t QCameraVideoChannel::releaseFrame(const void * opaque, bool isMetaData)
873 {
874 QCameraStream *pVideoStream = NULL;
875 for (size_t i = 0; i < mStreams.size(); i++) {
876 if (mStreams[i] != NULL && mStreams[i]->isTypeOf(CAM_STREAM_TYPE_VIDEO)) {
877 pVideoStream = mStreams[i];
878 break;
879 }
880 }
881
882 if (NULL == pVideoStream) {
883 LOGE("No video stream in the channel");
884 return BAD_VALUE;
885 }
886
887 int32_t rc = pVideoStream->bufDone(opaque, isMetaData);
888 return rc;
889 }
890
891 /*===========================================================================
892 * FUNCTION : QCameraReprocessChannel
893 *
894 * DESCRIPTION: constructor of QCameraReprocessChannel
895 *
896 * PARAMETERS :
897 * @cam_handle : camera handle
898 * @cam_ops : ptr to camera ops table
899 *
900 * RETURN : none
901 *==========================================================================*/
QCameraReprocessChannel(uint32_t cam_handle,mm_camera_ops_t * cam_ops)902 QCameraReprocessChannel::QCameraReprocessChannel(uint32_t cam_handle,
903 mm_camera_ops_t *cam_ops) :
904 QCameraChannel(cam_handle, cam_ops),
905 m_pSrcChannel(NULL),
906 mPassCount(0)
907 {
908 memset(mSrcStreamHandles, 0, sizeof(mSrcStreamHandles));
909 }
910
911 /*===========================================================================
912 * FUNCTION : QCameraReprocessChannel
913 *
914 * DESCRIPTION: default constructor of QCameraReprocessChannel
915 *
916 * PARAMETERS : none
917 *
918 * RETURN : none
919 *==========================================================================*/
QCameraReprocessChannel()920 QCameraReprocessChannel::QCameraReprocessChannel() :
921 m_pSrcChannel(NULL),
922 mPassCount(0)
923 {
924 }
925
926 /*===========================================================================
927 * FUNCTION : ~QCameraReprocessChannel
928 *
929 * DESCRIPTION: destructor of QCameraReprocessChannel
930 *
931 * PARAMETERS : none
932 *
933 * RETURN : none
934 *==========================================================================*/
~QCameraReprocessChannel()935 QCameraReprocessChannel::~QCameraReprocessChannel()
936 {
937 }
938
939 /*===========================================================================
940 * FUNCTION : addReprocStreamsFromSource
941 *
942 * DESCRIPTION: add reprocess streams from input source channel
943 *
944 * PARAMETERS :
945 * @allocator : stream related buffer allocator
946 * @featureConfig : pp feature configuration
947 * @pSrcChannel : ptr to input source channel that needs reprocess
948 * @minStreamBufNum: number of stream buffers needed
949 * @burstNum : number of burst captures needed
950 * @paddingInfo : padding information
951 * @param : reference to parameters
952 * @contStream : continous streaming mode or burst
953 * @offline : configure for offline reprocessing
954 *
955 * RETURN : int32_t type of status
956 * NO_ERROR -- success
957 * none-zero failure code
958 *==========================================================================*/
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)959 int32_t QCameraReprocessChannel::addReprocStreamsFromSource(
960 QCameraAllocator& allocator, cam_pp_feature_config_t &featureConfig,
961 QCameraChannel *pSrcChannel, uint8_t minStreamBufNum, uint8_t burstNum,
962 cam_padding_info_t *paddingInfo, QCameraParametersIntf ¶m, bool contStream,
963 bool offline)
964 {
965 int32_t rc = 0;
966 QCameraStream *pStream = NULL;
967 QCameraHeapMemory *pStreamInfoBuf = NULL;
968 QCameraHeapMemory *pMiscBuf = NULL;
969 cam_stream_info_t *streamInfo = NULL;
970 cam_padding_info_t padding;
971
972 memset(mSrcStreamHandles, 0, sizeof(mSrcStreamHandles));
973 if (NULL == paddingInfo) {
974 return BAD_VALUE;
975 }
976 padding = *paddingInfo;
977 //Use maximum padding so that the buffer
978 //can be rotated
979 padding.width_padding = MAX(padding.width_padding, padding.height_padding);
980 padding.height_padding = padding.width_padding;
981 padding.offset_info.offset_x = 0;
982 padding.offset_info.offset_y = 0;
983
984 LOGD("num of src stream = %d", pSrcChannel->getNumOfStreams());
985
986 for (uint32_t i = 0; i < pSrcChannel->getNumOfStreams(); i++) {
987 cam_pp_feature_config_t pp_featuremask = featureConfig;
988 pStream = pSrcChannel->getStreamByIndex(i);
989 if (pStream != NULL) {
990 if (param.getofflineRAW() && !((pStream->isTypeOf(CAM_STREAM_TYPE_RAW))
991 || (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW))
992 || (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA))
993 || (pStream->isOrignalTypeOf(CAM_STREAM_TYPE_RAW)))) {
994 //Skip all the stream other than RAW and POSTVIEW incase of offline of RAW
995 continue;
996 }
997
998 if (pStream->isTypeOf(CAM_STREAM_TYPE_RAW)
999 && (!param.getofflineRAW())) {
1000 // Skip raw for reprocess now because PP module cannot handle
1001 // meta data&raw. May need furthur discussion if Imaginglib need meta data
1002 continue;
1003 }
1004
1005 if (((pStream->isTypeOf(CAM_STREAM_TYPE_METADATA))
1006 && !(param.getManualCaptureMode() >=
1007 CAM_MANUAL_CAPTURE_TYPE_3))
1008 || (pStream->isTypeOf(CAM_STREAM_TYPE_ANALYSIS))) {
1009 // Skip metadata
1010 continue;
1011 }
1012
1013 if (pStream->isTypeOf(CAM_STREAM_TYPE_PREVIEW) ||
1014 pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW) ||
1015 pStream->isOrignalTypeOf(CAM_STREAM_TYPE_PREVIEW) ||
1016 pStream->isOrignalTypeOf(CAM_STREAM_TYPE_POSTVIEW)) {
1017 cam_feature_mask_t feature_mask = featureConfig.feature_mask;
1018
1019 // skip thumbnail reprocessing if not needed
1020 if (!param.needThumbnailReprocess(&feature_mask)) {
1021 continue;
1022 }
1023 // CAC, SHARPNESS, FLIP and WNR would have been already applied -
1024 // on preview/postview stream in realtime.
1025 // So, need not apply again.
1026 feature_mask &= ~(CAM_QCOM_FEATURE_DENOISE2D |
1027 CAM_QCOM_FEATURE_CAC |
1028 CAM_QCOM_FEATURE_SHARPNESS |
1029 CAM_QCOM_FEATURE_FLIP |
1030 CAM_QCOM_FEATURE_RAW_PROCESSING);
1031 if (!feature_mask) {
1032 // Skip thumbnail stream reprocessing since no other
1033 //reprocessing is enabled.
1034 continue;
1035 }
1036 }
1037
1038 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) {
1039 pp_featuremask.feature_mask = 0;
1040 pp_featuremask.feature_mask |= CAM_QCOM_FEATURE_METADATA_PROCESSING;
1041 }
1042
1043 pStreamInfoBuf = allocator.allocateStreamInfoBuf(CAM_STREAM_TYPE_OFFLINE_PROC);
1044 if (pStreamInfoBuf == NULL) {
1045 LOGE("no mem for stream info buf");
1046 rc = NO_MEMORY;
1047 break;
1048 }
1049
1050 streamInfo = (cam_stream_info_t *)pStreamInfoBuf->getPtr(0);
1051 memset(streamInfo, 0, sizeof(cam_stream_info_t));
1052 streamInfo->stream_type = CAM_STREAM_TYPE_OFFLINE_PROC;
1053 // Enable CPP high performance mode to put it in turbo frequency mode for
1054 // burst/longshot/HDR snapshot cases
1055 streamInfo->perf_mode = CAM_PERF_HIGH_PERFORMANCE;
1056 if (param.getofflineRAW() && pStream->isTypeOf(CAM_STREAM_TYPE_RAW)) {
1057 streamInfo->fmt = CAM_FORMAT_YUV_420_NV21;
1058 } else {
1059 rc = pStream->getFormat(streamInfo->fmt);
1060 }
1061
1062 if (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW) ||
1063 pStream->isTypeOf(CAM_STREAM_TYPE_PREVIEW)) {
1064 param.getThumbnailSize(&(streamInfo->dim.width), &(streamInfo->dim.height));
1065 } else {
1066 if ((param.isPostProcScaling()) &&
1067 (pp_featuremask.feature_mask & CAM_QCOM_FEATURE_SCALE)) {
1068 rc = param.getStreamDimension(CAM_STREAM_TYPE_OFFLINE_PROC,
1069 streamInfo->dim);
1070 } else if ((param.getofflineRAW()) &&
1071 (pStream->isTypeOf(CAM_STREAM_TYPE_RAW))) {
1072 param.getStreamDimension(CAM_STREAM_TYPE_SNAPSHOT,streamInfo->dim);
1073 } else {
1074 rc = pStream->getFrameDimension(streamInfo->dim);
1075 }
1076 }
1077
1078 if ( contStream ) {
1079 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
1080 streamInfo->num_of_burst = 0;
1081 } else {
1082 streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
1083 streamInfo->num_of_burst = burstNum;
1084 }
1085 streamInfo->num_bufs = minStreamBufNum;
1086
1087 cam_stream_reproc_config_t rp_cfg;
1088 memset(&rp_cfg, 0, sizeof(cam_stream_reproc_config_t));
1089 if (offline) {
1090 cam_frame_len_offset_t offset;
1091 memset(&offset, 0, sizeof(cam_frame_len_offset_t));
1092
1093 rp_cfg.pp_type = CAM_OFFLINE_REPROCESS_TYPE;
1094 pStream->getFormat(rp_cfg.offline.input_fmt);
1095 pStream->getFrameDimension(rp_cfg.offline.input_dim);
1096 pStream->getFrameOffset(offset);
1097 rp_cfg.offline.input_buf_planes.plane_info = offset;
1098 rp_cfg.offline.input_type = pStream->getMyOriginalType();
1099 //For input metadata + input buffer
1100 rp_cfg.offline.num_of_bufs = 2;
1101 } else {
1102 rp_cfg.pp_type = CAM_ONLINE_REPROCESS_TYPE;
1103 rp_cfg.online.input_stream_id = pStream->getMyServerID();
1104 rp_cfg.online.input_stream_type = pStream->getMyOriginalType();
1105 }
1106 param.getStreamRotation(streamInfo->stream_type,
1107 streamInfo->pp_config, streamInfo->dim);
1108 streamInfo->reprocess_config = rp_cfg;
1109 streamInfo->reprocess_config.pp_feature_config = pp_featuremask;
1110
1111 if (!(pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT)
1112 || pStream->isOrignalTypeOf(CAM_STREAM_TYPE_SNAPSHOT)
1113 || pStream->isTypeOf(CAM_STREAM_TYPE_RAW)
1114 || pStream->isOrignalTypeOf(CAM_STREAM_TYPE_RAW))) {
1115 // CAC, SHARPNESS, FLIP and WNR would have been already applied -
1116 // on preview/postview stream in realtime. Need not apply again.
1117 streamInfo->reprocess_config.pp_feature_config.feature_mask &=
1118 ~CAM_QCOM_FEATURE_CAC;
1119 streamInfo->reprocess_config.pp_feature_config.feature_mask &=
1120 ~CAM_QCOM_FEATURE_SHARPNESS;
1121 streamInfo->reprocess_config.pp_feature_config.feature_mask &=
1122 ~CAM_QCOM_FEATURE_FLIP;
1123 //Don't do WNR for thumbnail
1124 streamInfo->reprocess_config.pp_feature_config.feature_mask &=
1125 ~CAM_QCOM_FEATURE_DENOISE2D;
1126 streamInfo->reprocess_config.pp_feature_config.feature_mask &=
1127 ~CAM_QCOM_FEATURE_CDS;
1128 streamInfo->reprocess_config.pp_feature_config.feature_mask &=
1129 ~CAM_QCOM_FEATURE_DSDN;
1130 //No need of RAW processing for other than RAW streams
1131 streamInfo->reprocess_config.pp_feature_config.feature_mask &=
1132 ~CAM_QCOM_FEATURE_RAW_PROCESSING;
1133
1134 if (param.isHDREnabled()
1135 && !param.isHDRThumbnailProcessNeeded()){
1136 streamInfo->reprocess_config.pp_feature_config.feature_mask
1137 &= ~CAM_QCOM_FEATURE_HDR;
1138 }
1139 }
1140
1141 cam_stream_type_t type = CAM_STREAM_TYPE_DEFAULT;
1142 if (offline) {
1143 type = streamInfo->reprocess_config.offline.input_type;
1144 } else {
1145 type = streamInfo->reprocess_config.online.input_stream_type;
1146 }
1147 if (type == CAM_STREAM_TYPE_SNAPSHOT) {
1148 int flipMode = param.getFlipMode(type);
1149 if (flipMode > 0) {
1150 streamInfo->reprocess_config.pp_feature_config.feature_mask |=
1151 CAM_QCOM_FEATURE_FLIP;
1152 streamInfo->reprocess_config.pp_feature_config.flip = (uint32_t)flipMode;
1153 }
1154 }
1155
1156 if ((streamInfo->reprocess_config.pp_feature_config.feature_mask
1157 & CAM_QCOM_FEATURE_SCALE)
1158 && param.isReprocScaleEnabled()
1159 && param.isUnderReprocScaling()) {
1160 //we only Scale Snapshot frame
1161 if (pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT)) {
1162 streamInfo->dim.width =
1163 streamInfo->reprocess_config.pp_feature_config.scale_param.output_width;
1164 streamInfo->dim.height =
1165 streamInfo->reprocess_config.pp_feature_config.scale_param.output_height;
1166 }
1167 LOGH("stream width=%d, height=%d.",
1168 streamInfo->dim.width, streamInfo->dim.height);
1169 }
1170
1171 // save source stream handler
1172 mSrcStreamHandles[mStreams.size()] = pStream->getMyHandle();
1173
1174 pMiscBuf = allocator.allocateMiscBuf(streamInfo);
1175
1176 LOGH("Configure Reprocessing: stream = %d, res = %dX%d, fmt = %d, type = %d",
1177 pStream->getMyOriginalType(), streamInfo->dim.width,
1178 streamInfo->dim.height, streamInfo->fmt, type);
1179
1180 // add reprocess stream
1181 if (streamInfo->reprocess_config.pp_feature_config.feature_mask
1182 & CAM_QCOM_FEATURE_ROTATION) {
1183 rc = addStream(allocator, pStreamInfoBuf, pMiscBuf,
1184 minStreamBufNum, &padding, NULL, NULL, false, false,
1185 streamInfo->reprocess_config.pp_feature_config.rotation);
1186 } else {
1187 rc = addStream(allocator, pStreamInfoBuf, pMiscBuf,
1188 minStreamBufNum, &padding, NULL, NULL, false, false);
1189 }
1190 if (rc != NO_ERROR) {
1191 LOGE("add reprocess stream failed, ret = %d", rc);
1192 break;
1193 }
1194 }
1195 }
1196
1197 if (rc == NO_ERROR) {
1198 m_pSrcChannel = pSrcChannel;
1199 }
1200 return rc;
1201 }
1202
1203 /*===========================================================================
1204 * FUNCTION : getStreamBySrouceHandle
1205 *
1206 * DESCRIPTION: find reprocess stream by its source stream handle
1207 *
1208 * PARAMETERS :
1209 * @srcHandle : source stream handle
1210 *
1211 * RETURN : ptr to reprocess stream if found. NULL if not found
1212 *==========================================================================*/
getStreamBySrouceHandle(uint32_t srcHandle)1213 QCameraStream * QCameraReprocessChannel::getStreamBySrouceHandle(uint32_t srcHandle)
1214 {
1215 QCameraStream *pStream = NULL;
1216
1217 for (size_t i = 0; i < mStreams.size(); i++) {
1218 if (mSrcStreamHandles[i] == srcHandle) {
1219 pStream = mStreams[i];
1220 break;
1221 }
1222 }
1223
1224 return pStream;
1225 }
1226
1227 /*===========================================================================
1228 * FUNCTION : stop
1229 *
1230 * DESCRIPTION: stop channel and unmap offline buffers
1231 *
1232 * PARAMETERS : none
1233 *
1234 * RETURN : int32_t type of status
1235 * NO_ERROR -- success
1236 * none-zero failure code
1237 *==========================================================================*/
stop()1238 int32_t QCameraReprocessChannel::stop()
1239 {
1240 int32_t rc = QCameraChannel::stop();
1241
1242 if (!mOfflineBuffers.empty()) {
1243 QCameraStream *stream = NULL;
1244 List<OfflineBuffer>::iterator it = mOfflineBuffers.begin();
1245 int error = NO_ERROR;
1246 for( ; it != mOfflineBuffers.end(); it++) {
1247 stream = (*it).stream;
1248 if (NULL != stream) {
1249 error = stream->unmapBuf((*it).type,
1250 (*it).index,
1251 -1);
1252 if (NO_ERROR != error) {
1253 LOGE("Error during offline buffer unmap %d",
1254 error);
1255 }
1256 }
1257 }
1258 mOfflineBuffers.clear();
1259 }
1260 return rc;
1261 }
1262
1263 /*===========================================================================
1264 * FUNCTION : doReprocessOffline
1265 *
1266 * DESCRIPTION: request to do offline reprocess on the frame
1267 *
1268 * PARAMETERS :
1269 * @frame : frame to be performed a reprocess
1270 * @meta_buf : Metadata buffer for reprocessing
1271 * @pStream : Actual reprocess stream
1272 *
1273 * RETURN : int32_t type of status
1274 * NO_ERROR -- success
1275 * none-zero failure code
1276 *==========================================================================*/
doReprocessOffline(mm_camera_buf_def_t * frame,mm_camera_buf_def_t * meta_buf,QCameraStream * pStream)1277 int32_t QCameraReprocessChannel::doReprocessOffline(mm_camera_buf_def_t *frame,
1278 mm_camera_buf_def_t *meta_buf, QCameraStream *pStream)
1279 {
1280 int32_t rc = 0;
1281 OfflineBuffer mappedBuffer;
1282 uint32_t buf_index = 0;
1283 uint32_t meta_buf_index = 0;
1284
1285 if ((frame == NULL) || (meta_buf == NULL)) {
1286 LOGE("Invalid Input Paramters");
1287 return INVALID_OPERATION;
1288 }
1289
1290 if (pStream == NULL) {
1291 pStream = getStreamBySrouceHandle(frame->stream_id);
1292 if (pStream == NULL) {
1293 LOGE("Input validation failed.");
1294 return INVALID_OPERATION;
1295 }
1296 }
1297
1298 if (!mOfflineBuffers.empty()) {
1299 List<OfflineBuffer>::iterator it = mOfflineBuffers.begin();
1300 for( ; it != mOfflineBuffers.end(); it++) {
1301 buf_index = (buf_index < ((*it).index)) ? ((*it).index) : buf_index;
1302 }
1303 buf_index += 1;
1304 }
1305
1306 meta_buf_index = buf_index;
1307 if (meta_buf != NULL) {
1308 rc = pStream->mapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_META_BUF,
1309 meta_buf_index,
1310 -1,
1311 meta_buf->fd,
1312 meta_buf->buffer,
1313 meta_buf->frame_len);
1314 if (NO_ERROR != rc ) {
1315 LOGE("Error during metadata buffer mapping");
1316 rc = -1;
1317 return rc;
1318 }
1319
1320 mappedBuffer.index = meta_buf_index;
1321 mappedBuffer.stream = pStream;
1322 mappedBuffer.type = CAM_MAPPING_BUF_TYPE_OFFLINE_META_BUF;
1323 mOfflineBuffers.push_back(mappedBuffer);
1324 buf_index += 1;
1325 }
1326
1327 rc = pStream->mapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF,
1328 buf_index,
1329 -1,
1330 frame->fd,
1331 frame->buffer,
1332 frame->frame_len);
1333 if (NO_ERROR != rc ) {
1334 LOGE("Error during reprocess input buffer mapping");
1335 rc = -1;
1336 return rc;
1337 }
1338 mappedBuffer.index = buf_index;
1339 mappedBuffer.stream = pStream;
1340 mappedBuffer.type = CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF;
1341 mOfflineBuffers.push_back(mappedBuffer);
1342
1343 cam_stream_parm_buffer_t param;
1344 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t));
1345
1346 param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS;
1347 param.reprocess.buf_index = buf_index;
1348 param.reprocess.frame_idx = frame->frame_idx;
1349
1350 if (meta_buf != NULL) {
1351 param.reprocess.meta_present = 1;
1352 param.reprocess.meta_buf_index = meta_buf_index;
1353 }
1354
1355 LOGI("Offline reprocessing id = %d buf Id = %d meta index = %d type = %d",
1356 param.reprocess.frame_idx, param.reprocess.buf_index,
1357 param.reprocess.meta_buf_index, pStream->getMyOriginalType());
1358
1359 rc = pStream->setParameter(param);
1360 if (rc != NO_ERROR) {
1361 LOGE("stream setParameter for reprocess failed");
1362 return rc;
1363 }
1364 return rc;
1365 }
1366
1367 /*===========================================================================
1368 * FUNCTION : doReprocessOffline
1369 *
1370 * DESCRIPTION: request to do offline reprocess on the frame
1371 *
1372 * PARAMETERS :
1373 * @frame : frame to be performed a reprocess
1374 * @meta_buf : Metadata buffer for reprocessing
1375 * @mParameter : camera parameters
1376 *
1377 * RETURN : int32_t type of status
1378 * NO_ERROR -- success
1379 * none-zero failure code
1380 *==========================================================================*/
doReprocessOffline(mm_camera_super_buf_t * frame,mm_camera_buf_def_t * meta_buf,QCameraParametersIntf & mParameter)1381 int32_t QCameraReprocessChannel::doReprocessOffline(mm_camera_super_buf_t *frame,
1382 mm_camera_buf_def_t *meta_buf, QCameraParametersIntf &mParameter)
1383 {
1384 int32_t rc = 0;
1385 QCameraStream *pStream = NULL;
1386
1387 if (mStreams.size() < 1) {
1388 LOGE("No reprocess streams");
1389 return -1;
1390 }
1391 if (m_pSrcChannel == NULL) {
1392 LOGE("No source channel for reprocess");
1393 return -1;
1394 }
1395
1396 if (frame == NULL) {
1397 LOGE("Invalid source frame");
1398 return BAD_VALUE;
1399 }
1400
1401 for (uint32_t i = 0; i < frame->num_bufs; i++) {
1402 pStream = getStreamBySrouceHandle(frame->bufs[i]->stream_id);
1403 if ((pStream != NULL) &&
1404 (m_handle == pStream->getChannelHandle())) {
1405 if (mParameter.getofflineRAW() &&
1406 !((pStream->isOrignalTypeOf(CAM_STREAM_TYPE_RAW))
1407 || (pStream->isOrignalTypeOf(CAM_STREAM_TYPE_METADATA)))) {
1408 continue;
1409 }
1410
1411 if ((pStream->isOrignalTypeOf(CAM_STREAM_TYPE_METADATA)
1412 && (mParameter.getManualCaptureMode()
1413 < CAM_MANUAL_CAPTURE_TYPE_3))
1414 || (pStream->isTypeOf(CAM_STREAM_TYPE_ANALYSIS))) {
1415 // Skip metadata for reprocess now because PP module cannot handle meta data
1416 // May need furthur discussion if Imaginglib need meta data
1417 continue;
1418 }
1419
1420 // Update Metadata
1421 if (meta_buf != NULL) {
1422 uint32_t stream_id = frame->bufs[i]->stream_id;
1423 QCameraStream *srcStream =
1424 m_pSrcChannel->getStreamByHandle(stream_id);
1425 metadata_buffer_t *pMetaData =
1426 (metadata_buffer_t *)meta_buf->buffer;
1427 if ((NULL != pMetaData) && (NULL != srcStream)) {
1428 IF_META_AVAILABLE(cam_crop_data_t, crop,
1429 CAM_INTF_META_CROP_DATA, pMetaData) {
1430 if (MAX_NUM_STREAMS > crop->num_of_streams) {
1431 for (int j = 0; j < MAX_NUM_STREAMS; j++) {
1432 if (crop->crop_info[j].stream_id ==
1433 srcStream->getMyServerID()) {
1434 // Store crop/roi information for offline reprocess
1435 // in the reprocess stream slot
1436 crop->crop_info[crop->num_of_streams].crop =
1437 crop->crop_info[j].crop;
1438 crop->crop_info[crop->num_of_streams].roi_map =
1439 crop->crop_info[j].roi_map;
1440 for (uint8_t k = 0; k < mStreams.size(); k++) {
1441 if (srcStream->getMyType() ==
1442 mStreams[k]->getMyOriginalType()) {
1443 crop->crop_info[crop->num_of_streams].stream_id =
1444 mStreams[k]->getMyServerID();
1445 break;
1446 }
1447 }
1448 crop->num_of_streams++;
1449 break;
1450 }
1451 }
1452 } else {
1453 LOGE("No space to add reprocess stream crop/roi information");
1454 }
1455 }
1456 }
1457 }
1458
1459 if (mParameter.getofflineRAW()) {
1460 //For offline RAW reprocessing, make sure cache is clean & invalidated
1461 frame->bufs[i]->cache_flags |= CPU_HAS_READ_WRITTEN;
1462 }
1463 //Do Cache ops before sending to reprocess
1464 if (frame->bufs[i] != NULL) {
1465 pStream->handleCacheOps(frame->bufs[i]);
1466 }
1467 rc = doReprocessOffline (frame->bufs[i], meta_buf, pStream);
1468 }
1469 }
1470 return rc;
1471 }
1472
1473 /*===========================================================================
1474 * FUNCTION : doReprocess
1475 *
1476 * DESCRIPTION: request to do a reprocess on the frame
1477 *
1478 * PARAMETERS :
1479 * @frame : frame to be performed a reprocess
1480 * @mParameter : camera parameters
1481 * @pMetaStream: Metadata stream handle
1482 * @meta_buf_index : Metadata buffer index
1483 *
1484 * RETURN : int32_t type of status
1485 * NO_ERROR -- success
1486 * none-zero failure code
1487 *==========================================================================*/
doReprocess(mm_camera_super_buf_t * frame,QCameraParametersIntf & mParameter,QCameraStream * pMetaStream,uint8_t meta_buf_index)1488 int32_t QCameraReprocessChannel::doReprocess(mm_camera_super_buf_t *frame,
1489 QCameraParametersIntf &mParameter, QCameraStream *pMetaStream,
1490 uint8_t meta_buf_index)
1491 {
1492 int32_t rc = 0;
1493 if (mStreams.size() < 1) {
1494 LOGE("No reprocess streams");
1495 return -1;
1496 }
1497 if (m_pSrcChannel == NULL) {
1498 LOGE("No source channel for reprocess");
1499 return -1;
1500 }
1501
1502 if (pMetaStream == NULL) {
1503 LOGW("Null Metadata buffer for processing");
1504 }
1505
1506 for (uint32_t i = 0; i < frame->num_bufs; i++) {
1507 QCameraStream *pStream = getStreamBySrouceHandle(frame->bufs[i]->stream_id);
1508 if ((pStream != NULL) && (m_handle == pStream->getChannelHandle())) {
1509 if (mParameter.getofflineRAW() && !((pStream->isOrignalTypeOf(CAM_STREAM_TYPE_RAW))
1510 || (pStream->isOrignalTypeOf(CAM_STREAM_TYPE_POSTVIEW))
1511 || (pStream->isOrignalTypeOf(CAM_STREAM_TYPE_METADATA)))) {
1512 //Skip all the stream other than RAW and POSTVIEW incase of offline of RAW
1513 continue;
1514 }
1515 if ((pStream->isOrignalTypeOf(CAM_STREAM_TYPE_METADATA)
1516 && (mParameter.getManualCaptureMode()
1517 < CAM_MANUAL_CAPTURE_TYPE_3))
1518 || (pStream->isTypeOf(CAM_STREAM_TYPE_ANALYSIS))) {
1519 // Skip metadata for reprocess now because PP module cannot handle meta data
1520 // May need furthur discussion if Imaginglib need meta data
1521 continue;
1522 }
1523
1524 //Do Cache ops before sending to reprocess
1525 if (frame->bufs[i] != NULL) {
1526 pStream->handleCacheOps(frame->bufs[i]);
1527 }
1528
1529 cam_stream_parm_buffer_t param;
1530 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t));
1531 param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS;
1532 param.reprocess.buf_index = frame->bufs[i]->buf_idx;
1533 param.reprocess.frame_idx = frame->bufs[i]->frame_idx;
1534 if (pMetaStream != NULL) {
1535 // we have meta data frame bundled, sent together with reprocess frame
1536 param.reprocess.meta_present = 1;
1537 param.reprocess.meta_stream_handle = pMetaStream->getMyServerID();
1538 param.reprocess.meta_buf_index = meta_buf_index;
1539 }
1540
1541 LOGI("Online reprocessing id = %d buf Id = %d meta index = %d type = %d",
1542 param.reprocess.frame_idx, param.reprocess.buf_index,
1543 param.reprocess.meta_buf_index, pStream->getMyOriginalType());
1544
1545 rc = pStream->setParameter(param);
1546 if (rc != NO_ERROR) {
1547 LOGE("stream setParameter for reprocess failed");
1548 break;
1549 }
1550 }
1551 }
1552 return rc;
1553 }
1554
1555 /*===========================================================================
1556 * FUNCTION : doReprocess
1557 *
1558 * DESCRIPTION: request to do a reprocess on the frame
1559 *
1560 * PARAMETERS :
1561 * @buf_fd : fd to the input buffer that needs reprocess
1562 * @buffer : buffer pointer of actual buffer
1563 * @buf_lenght : length of the input buffer
1564 * @ret_val : result of reprocess.
1565 * Example: Could be faceID in case of register face image.
1566 *
1567 * RETURN : int32_t type of status
1568 * NO_ERROR -- success
1569 * none-zero failure code
1570 *==========================================================================*/
doReprocess(int buf_fd,void * buffer,size_t buf_length,int32_t & ret_val)1571 int32_t QCameraReprocessChannel::doReprocess(int buf_fd, void *buffer,
1572 size_t buf_length, int32_t &ret_val)
1573 {
1574 int32_t rc = 0;
1575 if (mStreams.size() < 1) {
1576 LOGE("No reprocess streams");
1577 return -1;
1578 }
1579
1580 uint32_t buf_idx = 0;
1581 for (size_t i = 0; i < mStreams.size(); i++) {
1582 if ((mStreams[i] != NULL) &&
1583 (m_handle != mStreams[i]->getChannelHandle())) {
1584 continue;
1585 }
1586 rc = mStreams[i]->mapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF,
1587 buf_idx, -1,
1588 buf_fd, buffer, buf_length);
1589
1590 if (rc == NO_ERROR) {
1591 cam_stream_parm_buffer_t param;
1592 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t));
1593 param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS;
1594 param.reprocess.buf_index = buf_idx;
1595 rc = mStreams[i]->setParameter(param);
1596 if (rc == NO_ERROR) {
1597 ret_val = param.reprocess.ret_val;
1598 }
1599 mStreams[i]->unmapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF,
1600 buf_idx, -1);
1601 }
1602 }
1603 return rc;
1604 }
1605
1606 }; // namespace qcamera
1607