1 /* Copyright (c) 2012-2014, The Linux Foundataion. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29
30 #define LOG_TAG "QCamera3Channel"
31 //#define LOG_NDEBUG 0
32
33 #include <stdlib.h>
34 #include <cstdlib>
35 #include <stdio.h>
36 #include <string.h>
37 #include <hardware/camera3.h>
38 #include <system/camera_metadata.h>
39 #include <gralloc_priv.h>
40 #include <utils/Log.h>
41 #include <utils/Errors.h>
42 #include <cutils/properties.h>
43 #include "QCamera3Channel.h"
44
45 using namespace android;
46
47 #define MIN_STREAMING_BUFFER_NUM 7+11
48
49 namespace qcamera {
50 static const char ExifAsciiPrefix[] =
51 { 0x41, 0x53, 0x43, 0x49, 0x49, 0x0, 0x0, 0x0 }; // "ASCII\0\0\0"
52 static const char ExifUndefinedPrefix[] =
53 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // "\0\0\0\0\0\0\0\0"
54
55 #define GPS_PROCESSING_METHOD_SIZE 101
56 #define EXIF_ASCII_PREFIX_SIZE 8 //(sizeof(ExifAsciiPrefix))
57 #define FOCAL_LENGTH_DECIMAL_PRECISION 100
58
59 /*===========================================================================
60 * FUNCTION : QCamera3Channel
61 *
62 * DESCRIPTION: constrcutor of QCamera3Channel
63 *
64 * PARAMETERS :
65 * @cam_handle : camera handle
66 * @cam_ops : ptr to camera ops table
67 *
68 * RETURN : none
69 *==========================================================================*/
QCamera3Channel(uint32_t cam_handle,mm_camera_ops_t * cam_ops,channel_cb_routine cb_routine,cam_padding_info_t * paddingInfo,void * userData)70 QCamera3Channel::QCamera3Channel(uint32_t cam_handle,
71 mm_camera_ops_t *cam_ops,
72 channel_cb_routine cb_routine,
73 cam_padding_info_t *paddingInfo,
74 void *userData)
75 {
76 m_camHandle = cam_handle;
77 m_camOps = cam_ops;
78 m_bIsActive = false;
79
80 m_handle = 0;
81 m_numStreams = 0;
82 memset(mStreams, 0, sizeof(mStreams));
83 mUserData = userData;
84
85 mStreamInfoBuf = NULL;
86 mChannelCB = cb_routine;
87 mPaddingInfo = paddingInfo;
88 }
89
90 /*===========================================================================
91 * FUNCTION : QCamera3Channel
92 *
93 * DESCRIPTION: default constrcutor of QCamera3Channel
94 *
95 * PARAMETERS : none
96 *
97 * RETURN : none
98 *==========================================================================*/
QCamera3Channel()99 QCamera3Channel::QCamera3Channel()
100 {
101 m_camHandle = 0;
102 m_camOps = NULL;
103 m_bIsActive = false;
104
105 m_handle = 0;
106 m_numStreams = 0;
107 memset(mStreams, 0, sizeof(mStreams));
108 mUserData = NULL;
109
110 mStreamInfoBuf = NULL;
111 mChannelCB = NULL;
112 mPaddingInfo = NULL;
113 }
114
115 /*===========================================================================
116 * FUNCTION : ~QCamera3Channel
117 *
118 * DESCRIPTION: destructor of QCamera3Channel
119 *
120 * PARAMETERS : none
121 *
122 * RETURN : none
123 *==========================================================================*/
~QCamera3Channel()124 QCamera3Channel::~QCamera3Channel()
125 {
126 if (m_bIsActive)
127 stop();
128
129 for (int i = 0; i < m_numStreams; i++) {
130 if (mStreams[i] != NULL) {
131 delete mStreams[i];
132 mStreams[i] = 0;
133 }
134 }
135 if (m_handle) {
136 m_camOps->delete_channel(m_camHandle, m_handle);
137 ALOGE("%s: deleting channel %d", __func__, m_handle);
138 m_handle = 0;
139 }
140 m_numStreams = 0;
141 }
142
143 /*===========================================================================
144 * FUNCTION : init
145 *
146 * DESCRIPTION: initialization of channel
147 *
148 * PARAMETERS :
149 * @attr : channel bundle attribute setting
150 * @dataCB : data notify callback
151 * @userData: user data ptr
152 *
153 * RETURN : int32_t type of status
154 * NO_ERROR -- success
155 * none-zero failure code
156 *==========================================================================*/
init(mm_camera_channel_attr_t * attr,mm_camera_buf_notify_t dataCB)157 int32_t QCamera3Channel::init(mm_camera_channel_attr_t *attr,
158 mm_camera_buf_notify_t dataCB)
159 {
160 m_handle = m_camOps->add_channel(m_camHandle,
161 attr,
162 dataCB,
163 this);
164 if (m_handle == 0) {
165 ALOGE("%s: Add channel failed", __func__);
166 return UNKNOWN_ERROR;
167 }
168 return NO_ERROR;
169 }
170
171 /*===========================================================================
172 * FUNCTION : addStream
173 *
174 * DESCRIPTION: add a stream into channel
175 *
176 * PARAMETERS :
177 * @allocator : stream related buffer allocator
178 * @streamInfoBuf : ptr to buf that constains stream info
179 * @minStreamBufNum: number of stream buffers needed
180 * @paddingInfo : padding information
181 * @stream_cb : stream data notify callback
182 * @userdata : user data ptr
183 *
184 * RETURN : int32_t type of status
185 * NO_ERROR -- success
186 * none-zero failure code
187 *==========================================================================*/
addStream(cam_stream_type_t streamType,cam_format_t streamFormat,cam_dimension_t streamDim,uint8_t minStreamBufNum)188 int32_t QCamera3Channel::addStream(cam_stream_type_t streamType,
189 cam_format_t streamFormat,
190 cam_dimension_t streamDim,
191 uint8_t minStreamBufNum)
192 {
193 int32_t rc = NO_ERROR;
194
195 if (m_numStreams >= 1) {
196 ALOGE("%s: Only one stream per channel supported in v3 Hal", __func__);
197 return BAD_VALUE;
198 }
199
200 if (m_numStreams >= MAX_STREAM_NUM_IN_BUNDLE) {
201 ALOGE("%s: stream number (%d) exceeds max limit (%d)",
202 __func__, m_numStreams, MAX_STREAM_NUM_IN_BUNDLE);
203 return BAD_VALUE;
204 }
205 QCamera3Stream *pStream = new QCamera3Stream(m_camHandle,
206 m_handle,
207 m_camOps,
208 mPaddingInfo,
209 this);
210 if (pStream == NULL) {
211 ALOGE("%s: No mem for Stream", __func__);
212 return NO_MEMORY;
213 }
214
215 rc = pStream->init(streamType, streamFormat, streamDim, NULL, minStreamBufNum,
216 streamCbRoutine, this);
217 if (rc == 0) {
218 mStreams[m_numStreams] = pStream;
219 m_numStreams++;
220 } else {
221 delete pStream;
222 }
223 return rc;
224 }
225
226 /*===========================================================================
227 * FUNCTION : start
228 *
229 * DESCRIPTION: start channel, which will start all streams belong to this channel
230 *
231 * PARAMETERS :
232 *
233 * RETURN : int32_t type of status
234 * NO_ERROR -- success
235 * none-zero failure code
236 *==========================================================================*/
start()237 int32_t QCamera3Channel::start()
238 {
239 int32_t rc = NO_ERROR;
240
241 if (m_numStreams > 1) {
242 ALOGE("%s: bundle not supported", __func__);
243 }
244
245 for (int i = 0; i < m_numStreams; i++) {
246 if (mStreams[i] != NULL) {
247 mStreams[i]->start();
248 }
249 }
250 rc = m_camOps->start_channel(m_camHandle, m_handle);
251
252 if (rc != NO_ERROR) {
253 for (int i = 0; i < m_numStreams; i++) {
254 if (mStreams[i] != NULL) {
255 mStreams[i]->stop();
256 }
257 }
258 } else {
259 m_bIsActive = true;
260 }
261
262 return rc;
263 }
264
265 /*===========================================================================
266 * FUNCTION : stop
267 *
268 * DESCRIPTION: stop a channel, which will stop all streams belong to this channel
269 *
270 * PARAMETERS : none
271 *
272 * RETURN : int32_t type of status
273 * NO_ERROR -- success
274 * none-zero failure code
275 *==========================================================================*/
stop()276 int32_t QCamera3Channel::stop()
277 {
278 int32_t rc = NO_ERROR;
279 if(!m_bIsActive) {
280 ALOGE("%s: Attempt to stop inactive channel",__func__);
281 return rc;
282 }
283
284 rc = m_camOps->stop_channel(m_camHandle, m_handle);
285
286 for (int i = 0; i < m_numStreams; i++) {
287 if (mStreams[i] != NULL) {
288 mStreams[i]->stop();
289 }
290 }
291
292 m_bIsActive = false;
293 return rc;
294 }
295
296 /*===========================================================================
297 * FUNCTION : bufDone
298 *
299 * DESCRIPTION: return a stream buf back to kernel
300 *
301 * PARAMETERS :
302 * @recvd_frame : stream buf frame to be returned
303 *
304 * RETURN : int32_t type of status
305 * NO_ERROR -- success
306 * none-zero failure code
307 *==========================================================================*/
bufDone(mm_camera_super_buf_t * recvd_frame)308 int32_t QCamera3Channel::bufDone(mm_camera_super_buf_t *recvd_frame)
309 {
310 int32_t rc = NO_ERROR;
311 for (int i = 0; i < recvd_frame->num_bufs; i++) {
312 if (recvd_frame->bufs[i] != NULL) {
313 for (int j = 0; j < m_numStreams; j++) {
314 if (mStreams[j] != NULL &&
315 mStreams[j]->getMyHandle() == recvd_frame->bufs[i]->stream_id) {
316 rc = mStreams[j]->bufDone(recvd_frame->bufs[i]->buf_idx);
317 break; // break loop j
318 }
319 }
320 }
321 }
322
323 return rc;
324 }
325
326 /*===========================================================================
327 * FUNCTION : getStreamTypeMask
328 *
329 * DESCRIPTION: Get bit mask of all stream types in this channel
330 *
331 * PARAMETERS : None
332 *
333 * RETURN : Bit mask of all stream types in this channel
334 *==========================================================================*/
getStreamTypeMask()335 uint32_t QCamera3Channel::getStreamTypeMask()
336 {
337 uint32_t mask = 0;
338 for (int i = 0; i < m_numStreams; i++) {
339 mask |= (0x1 << mStreams[i]->getMyType());
340 }
341 return mask;
342 }
343
344 /*===========================================================================
345 * FUNCTION : getStreamID
346 *
347 * DESCRIPTION: Get StreamID of requested stream type
348 *
349 * PARAMETERS : streamMask
350 *
351 * RETURN : Stream ID
352 *==========================================================================*/
getStreamID(uint32_t streamMask)353 uint32_t QCamera3Channel::getStreamID(uint32_t streamMask)
354 {
355 uint32_t streamID = 0;
356 for (int i = 0; i < m_numStreams; i++) {
357 if (streamMask == (uint32_t )(0x1 << mStreams[i]->getMyType())) {
358 streamID = mStreams[i]->getMyServerID();
359 break;
360 }
361 }
362 return streamID;
363 }
364
365 /*===========================================================================
366 * FUNCTION : getInternalFormatBuffer
367 *
368 * DESCRIPTION: return buffer in the internal format structure
369 *
370 * PARAMETERS :
371 * @streamHandle : buffer handle
372 *
373 * RETURN : stream object. NULL if not found
374 *==========================================================================*/
getInternalFormatBuffer(buffer_handle_t * buffer)375 mm_camera_buf_def_t* QCamera3RegularChannel::getInternalFormatBuffer(
376 buffer_handle_t * buffer)
377 {
378 int32_t index;
379 if(buffer == NULL)
380 return NULL;
381 index = mMemory->getMatchBufIndex((void*)buffer);
382 if(index < 0) {
383 ALOGE("%s: Could not find object among registered buffers",__func__);
384 return NULL;
385 }
386 return mStreams[0]->getInternalFormatBuffer(index);
387 }
388
389 /*===========================================================================
390 * FUNCTION : getStreamByHandle
391 *
392 * DESCRIPTION: return stream object by stream handle
393 *
394 * PARAMETERS :
395 * @streamHandle : stream handle
396 *
397 * RETURN : stream object. NULL if not found
398 *==========================================================================*/
getStreamByHandle(uint32_t streamHandle)399 QCamera3Stream *QCamera3Channel::getStreamByHandle(uint32_t streamHandle)
400 {
401 for (int i = 0; i < m_numStreams; i++) {
402 if (mStreams[i] != NULL && mStreams[i]->getMyHandle() == streamHandle) {
403 return mStreams[i];
404 }
405 }
406 return NULL;
407 }
408
409 /*===========================================================================
410 * FUNCTION : getStreamByIndex
411 *
412 * DESCRIPTION: return stream object by index
413 *
414 * PARAMETERS :
415 * @streamHandle : stream handle
416 *
417 * RETURN : stream object. NULL if not found
418 *==========================================================================*/
getStreamByIndex(uint8_t index)419 QCamera3Stream *QCamera3Channel::getStreamByIndex(uint8_t index)
420 {
421 if (index < m_numStreams) {
422 return mStreams[index];
423 }
424 return NULL;
425 }
426
427 /*===========================================================================
428 * FUNCTION : streamCbRoutine
429 *
430 * DESCRIPTION: callback routine for stream
431 *
432 * PARAMETERS :
433 * @streamHandle : stream handle
434 *
435 * RETURN : stream object. NULL if not found
436 *==========================================================================*/
streamCbRoutine(mm_camera_super_buf_t * super_frame,QCamera3Stream * stream,void * userdata)437 void QCamera3Channel::streamCbRoutine(mm_camera_super_buf_t *super_frame,
438 QCamera3Stream *stream, void *userdata)
439 {
440 QCamera3Channel *channel = (QCamera3Channel *)userdata;
441 if (channel == NULL) {
442 ALOGE("%s: invalid channel pointer", __func__);
443 return;
444 }
445 channel->streamCbRoutine(super_frame, stream);
446 }
447
448 /*===========================================================================
449 * FUNCTION : QCamera3RegularChannel
450 *
451 * DESCRIPTION: constrcutor of QCamera3RegularChannel
452 *
453 * PARAMETERS :
454 * @cam_handle : camera handle
455 * @cam_ops : ptr to camera ops table
456 * @cb_routine : callback routine to frame aggregator
457 * @stream : camera3_stream_t structure
458 *
459 * RETURN : none
460 *==========================================================================*/
QCamera3RegularChannel(uint32_t cam_handle,mm_camera_ops_t * cam_ops,channel_cb_routine cb_routine,cam_padding_info_t * paddingInfo,void * userData,camera3_stream_t * stream)461 QCamera3RegularChannel::QCamera3RegularChannel(uint32_t cam_handle,
462 mm_camera_ops_t *cam_ops,
463 channel_cb_routine cb_routine,
464 cam_padding_info_t *paddingInfo,
465 void *userData,
466 camera3_stream_t *stream) :
467 QCamera3Channel(cam_handle, cam_ops, cb_routine,
468 paddingInfo, userData),
469 mCamera3Stream(stream),
470 mNumBufs(0),
471 mCamera3Buffers(NULL),
472 mMemory(NULL),
473 mWidth(stream->width),
474 mHeight(stream->height)
475 {
476 }
477
478 /*===========================================================================
479 * FUNCTION : QCamera3RegularChannel
480 *
481 * DESCRIPTION: constrcutor of QCamera3RegularChannel
482 *
483 * PARAMETERS :
484 * @cam_handle : camera handle
485 * @cam_ops : ptr to camera ops table
486 * @cb_routine : callback routine to frame aggregator
487 * @stream : camera3_stream_t structure
488 *
489 * RETURN : none
490 *==========================================================================*/
QCamera3RegularChannel(uint32_t cam_handle,mm_camera_ops_t * cam_ops,channel_cb_routine cb_routine,cam_padding_info_t * paddingInfo,void * userData,camera3_stream_t * stream,uint32_t width,uint32_t height)491 QCamera3RegularChannel::QCamera3RegularChannel(uint32_t cam_handle,
492 mm_camera_ops_t *cam_ops,
493 channel_cb_routine cb_routine,
494 cam_padding_info_t *paddingInfo,
495 void *userData,
496 camera3_stream_t *stream,
497 uint32_t width, uint32_t height) :
498 QCamera3Channel(cam_handle, cam_ops, cb_routine,
499 paddingInfo, userData),
500 mCamera3Stream(stream),
501 mNumBufs(0),
502 mCamera3Buffers(NULL),
503 mMemory(NULL),
504 mWidth(width),
505 mHeight(height)
506 {
507 }
508
509 /*===========================================================================
510 * FUNCTION : ~QCamera3RegularChannel
511 *
512 * DESCRIPTION: destructor of QCamera3RegularChannel
513 *
514 * PARAMETERS : none
515 *
516 * RETURN : none
517 *==========================================================================*/
~QCamera3RegularChannel()518 QCamera3RegularChannel::~QCamera3RegularChannel()
519 {
520 if (mCamera3Buffers) {
521 delete[] mCamera3Buffers;
522 }
523 }
524
initialize()525 int32_t QCamera3RegularChannel::initialize()
526 {
527 //TO DO
528 return 0;
529 }
530
531 /*===========================================================================
532 * FUNCTION : request
533 *
534 * DESCRIPTION: process a request from camera service. Stream on if ncessary.
535 *
536 * PARAMETERS :
537 * @buffer : buffer to be filled for this request
538 *
539 * RETURN : 0 on a success start of capture
540 * -EINVAL on invalid input
541 * -ENODEV on serious error
542 *==========================================================================*/
request(buffer_handle_t * buffer,uint32_t frameNumber)543 int32_t QCamera3RegularChannel::request(buffer_handle_t *buffer, uint32_t frameNumber)
544 {
545 //FIX ME: Return buffer back in case of failures below.
546
547 int32_t rc = NO_ERROR;
548 int index;
549 if(!m_bIsActive) {
550 ALOGD("%s: First request on this channel starting stream",__func__);
551 start();
552 if(rc != NO_ERROR) {
553 ALOGE("%s: Failed to start the stream on the request",__func__);
554 return rc;
555 }
556 } else {
557 ALOGV("%s: Request on an existing stream",__func__);
558 }
559
560 if(!mMemory) {
561 ALOGE("%s: error, Gralloc Memory object not yet created for this stream",__func__);
562 return NO_MEMORY;
563 }
564
565 index = mMemory->getMatchBufIndex((void*)buffer);
566 if(index < 0) {
567 ALOGE("%s: Could not find object among registered buffers",__func__);
568 return DEAD_OBJECT;
569 }
570
571 rc = mStreams[0]->bufDone(index);
572 if(rc != NO_ERROR) {
573 ALOGE("%s: Failed to Q new buffer to stream",__func__);
574 return rc;
575 }
576
577 rc = mMemory->markFrameNumber(index, frameNumber);
578 return rc;
579 }
580
581 /*===========================================================================
582 * FUNCTION : registerBuffers
583 *
584 * DESCRIPTION: register streaming buffers to the channel object
585 *
586 * PARAMETERS :
587 * @num_buffers : number of buffers to be registered
588 * @buffers : buffer to be registered
589 *
590 * RETURN : 0 on a success start of capture
591 * -EINVAL on invalid input
592 * -ENOMEM on failure to register the buffer
593 * -ENODEV on serious error
594 *==========================================================================*/
registerBuffers(uint32_t num_buffers,buffer_handle_t ** buffers)595 int32_t QCamera3RegularChannel::registerBuffers(uint32_t num_buffers, buffer_handle_t **buffers)
596 {
597 int rc = 0;
598 struct private_handle_t *priv_handle = (struct private_handle_t *)(*buffers[0]);
599 cam_stream_type_t streamType;
600 cam_format_t streamFormat;
601 cam_dimension_t streamDim;
602
603 rc = init(NULL, NULL);
604 if (rc < 0) {
605 ALOGE("%s: init failed", __func__);
606 return rc;
607 }
608
609 if (mCamera3Stream->format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
610 if (priv_handle->flags & private_handle_t::PRIV_FLAGS_VIDEO_ENCODER) {
611 streamType = CAM_STREAM_TYPE_VIDEO;
612 streamFormat = CAM_FORMAT_YUV_420_NV12;
613 } else if (priv_handle->flags & private_handle_t::PRIV_FLAGS_HW_TEXTURE) {
614 streamType = CAM_STREAM_TYPE_PREVIEW;
615 streamFormat = CAM_FORMAT_YUV_420_NV21;
616 } else {
617 //TODO: Add a new flag in libgralloc for ZSL buffers, and its size needs
618 // to be properly aligned and padded.
619 ALOGE("%s: priv_handle->flags 0x%x not supported",
620 __func__, priv_handle->flags);
621 streamType = CAM_STREAM_TYPE_SNAPSHOT;
622 streamFormat = CAM_FORMAT_YUV_420_NV21;
623 }
624 } else if(mCamera3Stream->format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
625 streamType = CAM_STREAM_TYPE_CALLBACK;
626 streamFormat = CAM_FORMAT_YUV_420_NV21;
627 } else {
628 //TODO: Fail for other types of streams for now
629 ALOGE("%s: format is not IMPLEMENTATION_DEFINED or flexible", __func__);
630 return -EINVAL;
631 }
632
633 /* Bookkeep buffer set because they go out of scope after register call */
634 mNumBufs = num_buffers;
635 mCamera3Buffers = new buffer_handle_t*[num_buffers];
636 if (mCamera3Buffers == NULL) {
637 ALOGE("%s: Failed to allocate buffer_handle_t*", __func__);
638 return -ENOMEM;
639 }
640 for (size_t i = 0; i < num_buffers; i++)
641 mCamera3Buffers[i] = buffers[i];
642
643 streamDim.width = mWidth;
644 streamDim.height = mHeight;
645
646 rc = QCamera3Channel::addStream(streamType, streamFormat, streamDim,
647 num_buffers);
648 return rc;
649 }
650
streamCbRoutine(mm_camera_super_buf_t * super_frame,QCamera3Stream * stream)651 void QCamera3RegularChannel::streamCbRoutine(
652 mm_camera_super_buf_t *super_frame,
653 QCamera3Stream *stream)
654 {
655 //FIXME Q Buf back in case of error?
656 uint8_t frameIndex;
657 buffer_handle_t *resultBuffer;
658 int32_t resultFrameNumber;
659 camera3_stream_buffer_t result;
660
661 if(!super_frame) {
662 ALOGE("%s: Invalid Super buffer",__func__);
663 return;
664 }
665
666 if(super_frame->num_bufs != 1) {
667 ALOGE("%s: Multiple streams are not supported",__func__);
668 return;
669 }
670 if(super_frame->bufs[0] == NULL ) {
671 ALOGE("%s: Error, Super buffer frame does not contain valid buffer",
672 __func__);
673 return;
674 }
675
676 frameIndex = (uint8_t)super_frame->bufs[0]->buf_idx;
677 if(frameIndex >= mNumBufs) {
678 ALOGE("%s: Error, Invalid index for buffer",__func__);
679 if(stream) {
680 stream->bufDone(frameIndex);
681 }
682 return;
683 }
684
685 ////Use below data to issue framework callback
686 resultBuffer = mCamera3Buffers[frameIndex];
687 resultFrameNumber = mMemory->getFrameNumber(frameIndex);
688
689 result.stream = mCamera3Stream;
690 result.buffer = resultBuffer;
691 result.status = CAMERA3_BUFFER_STATUS_OK;
692 result.acquire_fence = -1;
693 result.release_fence = -1;
694
695 mChannelCB(NULL, &result, resultFrameNumber, mUserData);
696 free(super_frame);
697 return;
698 }
699
getStreamBufs(uint32_t)700 QCamera3Memory* QCamera3RegularChannel::getStreamBufs(uint32_t /*len*/)
701 {
702 if (mNumBufs == 0 || mCamera3Buffers == NULL) {
703 ALOGE("%s: buffers not registered yet", __func__);
704 return NULL;
705 }
706
707 mMemory = new QCamera3GrallocMemory();
708 if (mMemory == NULL) {
709 return NULL;
710 }
711
712 if (mMemory->registerBuffers(mNumBufs, mCamera3Buffers) < 0) {
713 delete mMemory;
714 mMemory = NULL;
715 return NULL;
716 }
717 return mMemory;
718 }
719
putStreamBufs()720 void QCamera3RegularChannel::putStreamBufs()
721 {
722 mMemory->unregisterBuffers();
723 delete mMemory;
724 mMemory = NULL;
725 }
726
727 int QCamera3RegularChannel::kMaxBuffers = 7;
728
QCamera3MetadataChannel(uint32_t cam_handle,mm_camera_ops_t * cam_ops,channel_cb_routine cb_routine,cam_padding_info_t * paddingInfo,void * userData)729 QCamera3MetadataChannel::QCamera3MetadataChannel(uint32_t cam_handle,
730 mm_camera_ops_t *cam_ops,
731 channel_cb_routine cb_routine,
732 cam_padding_info_t *paddingInfo,
733 void *userData) :
734 QCamera3Channel(cam_handle, cam_ops,
735 cb_routine, paddingInfo, userData),
736 mMemory(NULL)
737 {
738 }
739
~QCamera3MetadataChannel()740 QCamera3MetadataChannel::~QCamera3MetadataChannel()
741 {
742 if (m_bIsActive)
743 stop();
744
745 if (mMemory) {
746 mMemory->deallocate();
747 delete mMemory;
748 mMemory = NULL;
749 }
750 }
751
initialize()752 int32_t QCamera3MetadataChannel::initialize()
753 {
754 int32_t rc;
755 cam_dimension_t streamDim;
756
757 if (mMemory || m_numStreams > 0) {
758 ALOGE("%s: metadata channel already initialized", __func__);
759 return -EINVAL;
760 }
761
762 rc = init(NULL, NULL);
763 if (rc < 0) {
764 ALOGE("%s: init failed", __func__);
765 return rc;
766 }
767
768 streamDim.width = sizeof(metadata_buffer_t),
769 streamDim.height = 1;
770 rc = QCamera3Channel::addStream(CAM_STREAM_TYPE_METADATA, CAM_FORMAT_MAX,
771 streamDim, MIN_STREAMING_BUFFER_NUM);
772 if (rc < 0) {
773 ALOGE("%s: addStream failed", __func__);
774 }
775 return rc;
776 }
777
request(buffer_handle_t *,uint32_t)778 int32_t QCamera3MetadataChannel::request(buffer_handle_t * /*buffer*/,
779 uint32_t /*frameNumber*/)
780 {
781 if (!m_bIsActive) {
782 return start();
783 }
784 else
785 return 0;
786 }
787
registerBuffers(uint32_t,buffer_handle_t **)788 int32_t QCamera3MetadataChannel::registerBuffers(uint32_t /*num_buffers*/,
789 buffer_handle_t ** /*buffers*/)
790 {
791 // no registerBuffers are supported for metadata channel
792 return -EINVAL;
793 }
794
streamCbRoutine(mm_camera_super_buf_t * super_frame,QCamera3Stream *)795 void QCamera3MetadataChannel::streamCbRoutine(
796 mm_camera_super_buf_t *super_frame,
797 QCamera3Stream * /*stream*/)
798 {
799 uint32_t requestNumber = 0;
800 if (super_frame == NULL || super_frame->num_bufs != 1) {
801 ALOGE("%s: super_frame is not valid", __func__);
802 return;
803 }
804 mChannelCB(super_frame, NULL, requestNumber, mUserData);
805 }
806
getStreamBufs(uint32_t len)807 QCamera3Memory* QCamera3MetadataChannel::getStreamBufs(uint32_t len)
808 {
809 int rc;
810 if (len < sizeof(metadata_buffer_t)) {
811 ALOGE("%s: size doesn't match %d vs %d", __func__,
812 len, sizeof(metadata_buffer_t));
813 return NULL;
814 }
815 mMemory = new QCamera3HeapMemory();
816 if (!mMemory) {
817 ALOGE("%s: unable to create metadata memory", __func__);
818 return NULL;
819 }
820 rc = mMemory->allocate(MIN_STREAMING_BUFFER_NUM, len, true);
821 if (rc < 0) {
822 ALOGE("%s: unable to allocate metadata memory", __func__);
823 delete mMemory;
824 mMemory = NULL;
825 return NULL;
826 }
827 memset(mMemory->getPtr(0), 0, sizeof(metadata_buffer_t));
828 return mMemory;
829 }
830
putStreamBufs()831 void QCamera3MetadataChannel::putStreamBufs()
832 {
833 mMemory->deallocate();
834 delete mMemory;
835 mMemory = NULL;
836 }
837
838 /*===========================================================================
839 * FUNCTION : jpegEvtHandle
840 *
841 * DESCRIPTION: Function registerd to mm-jpeg-interface to handle jpeg events.
842 Construct result payload and call mChannelCb to deliver buffer
843 to framework.
844 *
845 * PARAMETERS :
846 * @status : status of jpeg job
847 * @client_hdl: jpeg client handle
848 * @jobId : jpeg job Id
849 * @p_ouput : ptr to jpeg output result struct
850 * @userdata : user data ptr
851 *
852 * RETURN : none
853 *==========================================================================*/
jpegEvtHandle(jpeg_job_status_t status,uint32_t,uint32_t jobId,mm_jpeg_output_t * p_output,void * userdata)854 void QCamera3PicChannel::jpegEvtHandle(jpeg_job_status_t status,
855 uint32_t /*client_hdl*/,
856 uint32_t jobId,
857 mm_jpeg_output_t *p_output,
858 void *userdata)
859 {
860 buffer_handle_t *resultBuffer;
861 int32_t resultFrameNumber;
862 int resultStatus = CAMERA3_BUFFER_STATUS_OK;
863 camera3_stream_buffer_t result;
864 camera3_jpeg_blob_t jpegHeader;
865 char* jpeg_eof = 0;
866 int maxJpegSize;
867 QCamera3PicChannel *obj = (QCamera3PicChannel *)userdata;
868 if (obj) {
869
870 //Release any cached metabuffer information
871 if (obj->mMetaFrame != NULL && obj->m_pMetaChannel != NULL) {
872 ((QCamera3MetadataChannel*)(obj->m_pMetaChannel))->bufDone(obj->mMetaFrame);
873 obj->mMetaFrame = NULL;
874 obj->m_pMetaChannel = NULL;
875 } else {
876 ALOGE("%s: Meta frame was NULL", __func__);
877 }
878 //Construct payload for process_capture_result. Call mChannelCb
879
880 qcamera_jpeg_data_t *job = obj->m_postprocessor.findJpegJobByJobId(jobId);
881
882 if ((job == NULL) || (status == JPEG_JOB_STATUS_ERROR)) {
883 ALOGE("%s: Error in jobId: (%d) with status: %d", __func__, jobId, status);
884 resultStatus = CAMERA3_BUFFER_STATUS_ERROR;
885 }
886
887 //Construct jpeg transient header of type camera3_jpeg_blob_t
888 //Append at the end of jpeg image of buf_filled_len size
889
890 jpegHeader.jpeg_blob_id = CAMERA3_JPEG_BLOB_ID;
891 jpegHeader.jpeg_size = p_output->buf_filled_len;
892
893
894 char* jpeg_buf = (char *)p_output->buf_vaddr;
895
896 if(obj->mJpegSettings->max_jpeg_size <= 0 ||
897 obj->mJpegSettings->max_jpeg_size > obj->mMemory->getSize(obj->mCurrentBufIndex)){
898 ALOGW("%s:Max Jpeg size :%d is out of valid range setting to size of buffer",
899 __func__, obj->mJpegSettings->max_jpeg_size);
900 maxJpegSize = obj->mMemory->getSize(obj->mCurrentBufIndex);
901 } else {
902 maxJpegSize = obj->mJpegSettings->max_jpeg_size;
903 ALOGI("%s: Setting max jpeg size to %d",__func__, maxJpegSize);
904 }
905 jpeg_eof = &jpeg_buf[maxJpegSize-sizeof(jpegHeader)];
906 memcpy(jpeg_eof, &jpegHeader, sizeof(jpegHeader));
907 obj->mMemory->cleanInvalidateCache(obj->mCurrentBufIndex);
908
909 ////Use below data to issue framework callback
910 resultBuffer = obj->mCamera3Buffers[obj->mCurrentBufIndex];
911 resultFrameNumber = obj->mMemory->getFrameNumber(obj->mCurrentBufIndex);
912
913 result.stream = obj->mCamera3Stream;
914 result.buffer = resultBuffer;
915 result.status = resultStatus;
916 result.acquire_fence = -1;
917 result.release_fence = -1;
918
919 ALOGV("%s: Issue Callback", __func__);
920 obj->mChannelCB(NULL, &result, resultFrameNumber, obj->mUserData);
921
922 // release internal data for jpeg job
923 if (job != NULL) {
924 obj->m_postprocessor.releaseJpegJobData(job);
925 free(job);
926 }
927 return;
928 // }
929 } else {
930 ALOGE("%s: Null userdata in jpeg callback", __func__);
931 }
932 }
933
QCamera3PicChannel(uint32_t cam_handle,mm_camera_ops_t * cam_ops,channel_cb_routine cb_routine,cam_padding_info_t * paddingInfo,void * userData,camera3_stream_t * stream)934 QCamera3PicChannel::QCamera3PicChannel(uint32_t cam_handle,
935 mm_camera_ops_t *cam_ops,
936 channel_cb_routine cb_routine,
937 cam_padding_info_t *paddingInfo,
938 void *userData,
939 camera3_stream_t *stream) :
940 QCamera3Channel(cam_handle, cam_ops, cb_routine,
941 paddingInfo, userData),
942 m_postprocessor(this),
943 mCamera3Stream(stream),
944 mNumBufs(0),
945 mCamera3Buffers(NULL),
946 mJpegSettings(NULL),
947 mCurrentBufIndex(-1),
948 mMemory(NULL),
949 mYuvMemory(NULL),
950 mMetaFrame(NULL)
951 {
952 int32_t rc = m_postprocessor.init(jpegEvtHandle, this);
953 if (rc != 0) {
954 ALOGE("Init Postprocessor failed");
955 }
956 }
957
~QCamera3PicChannel()958 QCamera3PicChannel::~QCamera3PicChannel()
959 {
960 int32_t rc = m_postprocessor.deinit();
961 if (rc != 0) {
962 ALOGE("De-init Postprocessor failed");
963 }
964 if (mCamera3Buffers) {
965 delete[] mCamera3Buffers;
966 }
967 }
968
initialize()969 int32_t QCamera3PicChannel::initialize()
970 {
971 int32_t rc = NO_ERROR;
972 cam_dimension_t streamDim;
973 cam_stream_type_t streamType;
974 cam_format_t streamFormat;
975 mm_camera_channel_attr_t attr;
976
977 memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
978 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
979 attr.look_back = 1;
980 attr.post_frame_skip = 1;
981 attr.water_mark = 1;
982 attr.max_unmatched_frames = 1;
983
984 rc = init(&attr, NULL);
985 if (rc < 0) {
986 ALOGE("%s: init failed", __func__);
987 return rc;
988 }
989
990 streamType = CAM_STREAM_TYPE_NON_ZSL_SNAPSHOT;
991 streamFormat = CAM_FORMAT_YUV_420_NV21;
992 streamDim.width = mCamera3Stream->width;
993 streamDim.height = mCamera3Stream->height;
994
995 int num_buffers = 1;
996
997 rc = QCamera3Channel::addStream(streamType, streamFormat, streamDim,
998 num_buffers);
999
1000 return rc;
1001 }
1002
request(buffer_handle_t * buffer,uint32_t frameNumber,jpeg_settings_t * jpegSettings,mm_camera_buf_def_t * pInputBuffer,QCamera3Channel * pInputChannel)1003 int32_t QCamera3PicChannel::request(buffer_handle_t *buffer,
1004 uint32_t frameNumber, jpeg_settings_t* jpegSettings,
1005 mm_camera_buf_def_t *pInputBuffer,QCamera3Channel* pInputChannel)
1006 {
1007 //FIX ME: Return buffer back in case of failures below.
1008
1009 int32_t rc = NO_ERROR;
1010 int index;
1011 mJpegSettings = jpegSettings;
1012 // Picture stream has already been started before any request comes in
1013 if (!m_bIsActive) {
1014 ALOGE("%s: Picture stream should have been started before any request",
1015 __func__);
1016 return -EINVAL;
1017 }
1018 if (pInputBuffer == NULL)
1019 mStreams[0]->bufDone(0);
1020
1021 if(!mMemory) {
1022 if(pInputBuffer) {
1023 mMemory = new QCamera3GrallocMemory();
1024 if (mMemory == NULL) {
1025 return NO_MEMORY;
1026 }
1027
1028 //Registering Jpeg output buffer
1029 if (mMemory->registerBuffers(mNumBufs, mCamera3Buffers) < 0) {
1030 delete mMemory;
1031 mMemory = NULL;
1032 return NO_MEMORY;
1033 }
1034 } else {
1035 ALOGE("%s: error, Gralloc Memory object not yet created for this stream",__func__);
1036 return NO_MEMORY;
1037 }
1038 }
1039
1040 index = mMemory->getMatchBufIndex((void*)buffer);
1041 if(index < 0) {
1042 ALOGE("%s: Could not find object among registered buffers",__func__);
1043 return DEAD_OBJECT;
1044 }
1045 rc = mMemory->markFrameNumber(index, frameNumber);
1046
1047 //Start the postprocessor for jpeg encoding. Pass mMemory as destination buffer
1048 mCurrentBufIndex = index;
1049
1050 if(pInputBuffer) {
1051 m_postprocessor.start(mMemory, index, pInputChannel);
1052 ALOGD("%s: Post-process started", __func__);
1053 ALOGD("%s: Issue call to reprocess", __func__);
1054 m_postprocessor.processAuxiliaryData(pInputBuffer,pInputChannel);
1055 } else {
1056 m_postprocessor.start(mMemory, index, this);
1057 }
1058 return rc;
1059 }
1060
1061 /*===========================================================================
1062 * FUNCTION : dataNotifyCB
1063 *
1064 * DESCRIPTION: Channel Level callback used for super buffer data notify.
1065 * This function is registered with mm-camera-interface to handle
1066 * data notify
1067 *
1068 * PARAMETERS :
1069 * @recvd_frame : stream frame received
1070 * userdata : user data ptr
1071 *
1072 * RETURN : none
1073 *==========================================================================*/
dataNotifyCB(mm_camera_super_buf_t * recvd_frame,void * userdata)1074 void QCamera3PicChannel::dataNotifyCB(mm_camera_super_buf_t *recvd_frame,
1075 void *userdata)
1076 {
1077 ALOGV("%s: E\n", __func__);
1078 QCamera3PicChannel *channel = (QCamera3PicChannel *)userdata;
1079
1080 if (channel == NULL) {
1081 ALOGE("%s: invalid channel pointer", __func__);
1082 return;
1083 }
1084
1085 if(channel->m_numStreams != 1) {
1086 ALOGE("%s: Error: Bug: This callback assumes one stream per channel",__func__);
1087 return;
1088 }
1089
1090
1091 if(channel->mStreams[0] == NULL) {
1092 ALOGE("%s: Error: Invalid Stream object",__func__);
1093 return;
1094 }
1095
1096 channel->QCamera3PicChannel::streamCbRoutine(recvd_frame, channel->mStreams[0]);
1097
1098 ALOGV("%s: X\n", __func__);
1099 return;
1100 }
1101
1102
registerBuffers(uint32_t num_buffers,buffer_handle_t ** buffers)1103 int32_t QCamera3PicChannel::registerBuffers(uint32_t num_buffers,
1104 buffer_handle_t **buffers)
1105 {
1106 int rc = 0;
1107 cam_stream_type_t streamType;
1108 cam_format_t streamFormat;
1109
1110 ALOGV("%s: E",__func__);
1111 rc = QCamera3PicChannel::initialize();
1112 if (rc < 0) {
1113 ALOGE("%s: init failed", __func__);
1114 return rc;
1115 }
1116
1117 if (mCamera3Stream->format == HAL_PIXEL_FORMAT_BLOB) {
1118 streamType = CAM_STREAM_TYPE_NON_ZSL_SNAPSHOT;
1119 streamFormat = CAM_FORMAT_YUV_420_NV21;
1120 } else {
1121 //TODO: Fail for other types of streams for now
1122 ALOGE("%s: format is not BLOB", __func__);
1123 return -EINVAL;
1124 }
1125 /* Bookkeep buffer set because they go out of scope after register call */
1126 mNumBufs = num_buffers;
1127 mCamera3Buffers = new buffer_handle_t*[num_buffers];
1128 if (mCamera3Buffers == NULL) {
1129 ALOGE("%s: Failed to allocate buffer_handle_t*", __func__);
1130 return -ENOMEM;
1131 }
1132 for (size_t i = 0; i < num_buffers; i++)
1133 mCamera3Buffers[i] = buffers[i];
1134
1135 ALOGV("%s: X",__func__);
1136 return rc;
1137 }
1138
streamCbRoutine(mm_camera_super_buf_t * super_frame,QCamera3Stream * stream)1139 void QCamera3PicChannel::streamCbRoutine(mm_camera_super_buf_t *super_frame,
1140 QCamera3Stream *stream)
1141 {
1142 //TODO
1143 //Used only for getting YUV. Jpeg callback will be sent back from channel
1144 //directly to HWI. Refer to func jpegEvtHandle
1145
1146 //Got the yuv callback. Calling yuv callback handler in PostProc
1147 uint8_t frameIndex;
1148 mm_camera_super_buf_t* frame = NULL;
1149 if(!super_frame) {
1150 ALOGE("%s: Invalid Super buffer",__func__);
1151 return;
1152 }
1153
1154 if(super_frame->num_bufs != 1) {
1155 ALOGE("%s: Multiple streams are not supported",__func__);
1156 return;
1157 }
1158 if(super_frame->bufs[0] == NULL ) {
1159 ALOGE("%s: Error, Super buffer frame does not contain valid buffer",
1160 __func__);
1161 return;
1162 }
1163
1164 frameIndex = (uint8_t)super_frame->bufs[0]->buf_idx;
1165 if(frameIndex >= mNumBufs) {
1166 ALOGE("%s: Error, Invalid index for buffer",__func__);
1167 if(stream) {
1168 stream->bufDone(frameIndex);
1169 }
1170 return;
1171 }
1172
1173 frame = (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t));
1174 if (frame == NULL) {
1175 ALOGE("%s: Error allocating memory to save received_frame structure.",
1176 __func__);
1177 if(stream) {
1178 stream->bufDone(frameIndex);
1179 }
1180 return;
1181 }
1182 *frame = *super_frame;
1183
1184 m_postprocessor.processData(frame);
1185 free(super_frame);
1186 return;
1187 }
1188
getStreamBufs(uint32_t len)1189 QCamera3Memory* QCamera3PicChannel::getStreamBufs(uint32_t len)
1190 {
1191 int rc = 0;
1192
1193 if (mNumBufs == 0 || mCamera3Buffers == NULL) {
1194 ALOGE("%s: buffers not registered yet", __func__);
1195 return NULL;
1196 }
1197
1198 if(mMemory) {
1199 delete mMemory;
1200 mMemory = NULL;
1201 }
1202 mMemory = new QCamera3GrallocMemory();
1203 if (mMemory == NULL) {
1204 return NULL;
1205 }
1206
1207 //Registering Jpeg output buffer
1208 if (mMemory->registerBuffers(mNumBufs, mCamera3Buffers) < 0) {
1209 delete mMemory;
1210 mMemory = NULL;
1211 return NULL;
1212 }
1213
1214 mYuvMemory = new QCamera3HeapMemory();
1215 if (!mYuvMemory) {
1216 ALOGE("%s: unable to create metadata memory", __func__);
1217 return NULL;
1218 }
1219
1220 //Queue YUV buffers in the beginning mQueueAll = true
1221 rc = mYuvMemory->allocate(1, len, false);
1222 if (rc < 0) {
1223 ALOGE("%s: unable to allocate metadata memory", __func__);
1224 delete mYuvMemory;
1225 mYuvMemory = NULL;
1226 return NULL;
1227 }
1228 return mYuvMemory;
1229 }
1230
putStreamBufs()1231 void QCamera3PicChannel::putStreamBufs()
1232 {
1233 mMemory->unregisterBuffers();
1234 delete mMemory;
1235 mMemory = NULL;
1236
1237 mYuvMemory->deallocate();
1238 delete mYuvMemory;
1239 mYuvMemory = NULL;
1240 }
1241
isRawSnapshot()1242 bool QCamera3PicChannel::isRawSnapshot()
1243 {
1244 return !(mJpegSettings->is_jpeg_format);
1245 }
1246 /*===========================================================================
1247 * FUNCTION : getThumbnailSize
1248 *
1249 * DESCRIPTION: get user set thumbnail size
1250 *
1251 * PARAMETERS :
1252 * @dim : output of thumbnail dimension
1253 *
1254 * RETURN : none
1255 *==========================================================================*/
getThumbnailSize(cam_dimension_t & dim)1256 void QCamera3PicChannel::getThumbnailSize(cam_dimension_t &dim)
1257 {
1258 dim = mJpegSettings->thumbnail_size;
1259 }
1260
1261 /*===========================================================================
1262 * FUNCTION : getJpegQuality
1263 *
1264 * DESCRIPTION: get user set jpeg quality
1265 *
1266 * PARAMETERS : none
1267 *
1268 * RETURN : jpeg quality setting
1269 *==========================================================================*/
getJpegQuality()1270 int QCamera3PicChannel::getJpegQuality()
1271 {
1272 int quality = mJpegSettings->jpeg_quality;
1273 if (quality < 0) {
1274 quality = 85; //set to default quality value
1275 }
1276 return quality;
1277 }
1278
1279 /*===========================================================================
1280 * FUNCTION : getJpegRotation
1281 *
1282 * DESCRIPTION: get rotation information to be passed into jpeg encoding
1283 *
1284 * PARAMETERS : none
1285 *
1286 * RETURN : rotation information
1287 *==========================================================================*/
getJpegRotation()1288 int QCamera3PicChannel::getJpegRotation() {
1289 int rotation = mJpegSettings->jpeg_orientation;
1290 if (rotation < 0) {
1291 rotation = 0;
1292 }
1293 return rotation;
1294 }
1295
queueMetadata(mm_camera_super_buf_t * metadata_buf,QCamera3Channel * pMetaChannel,bool relinquish)1296 void QCamera3PicChannel::queueMetadata(mm_camera_super_buf_t *metadata_buf,
1297 QCamera3Channel *pMetaChannel,
1298 bool relinquish)
1299 {
1300 if(relinquish)
1301 mMetaFrame = metadata_buf;
1302 m_pMetaChannel = pMetaChannel;
1303 m_postprocessor.processPPMetadata(metadata_buf);
1304 }
1305 /*===========================================================================
1306 * FUNCTION : getRational
1307 *
1308 * DESCRIPTION: compose rational struct
1309 *
1310 * PARAMETERS :
1311 * @rat : ptr to struct to store rational info
1312 * @num :num of the rational
1313 * @denom : denom of the rational
1314 *
1315 * RETURN : int32_t type of status
1316 * NO_ERROR -- success
1317 * none-zero failure code
1318 *==========================================================================*/
getRational(rat_t * rat,int num,int denom)1319 int32_t getRational(rat_t *rat, int num, int denom)
1320 {
1321 if (NULL == rat) {
1322 ALOGE("%s: NULL rat input", __func__);
1323 return BAD_VALUE;
1324 }
1325 rat->num = num;
1326 rat->denom = denom;
1327 return NO_ERROR;
1328 }
1329
1330 /*===========================================================================
1331 * FUNCTION : parseGPSCoordinate
1332 *
1333 * DESCRIPTION: parse GPS coordinate string
1334 *
1335 * PARAMETERS :
1336 * @coord_str : [input] coordinate string
1337 * @coord : [output] ptr to struct to store coordinate
1338 *
1339 * RETURN : int32_t type of status
1340 * NO_ERROR -- success
1341 * none-zero failure code
1342 *==========================================================================*/
parseGPSCoordinate(const char * coord_str,rat_t * coord)1343 int parseGPSCoordinate(const char *coord_str, rat_t* coord)
1344 {
1345 if(coord == NULL) {
1346 ALOGE("%s: error, invalid argument coord == NULL", __func__);
1347 return BAD_VALUE;
1348 }
1349 float degF = atof(coord_str);
1350 if (degF < 0) {
1351 degF = -degF;
1352 }
1353 float minF = (degF - (int) degF) * 60;
1354 float secF = (minF - (int) minF) * 60;
1355
1356 getRational(&coord[0], (int)degF, 1);
1357 getRational(&coord[1], (int)minF, 1);
1358 getRational(&coord[2], (int)(secF * 10000), 10000);
1359 return NO_ERROR;
1360 }
1361
1362 /*===========================================================================
1363 * FUNCTION : getExifDateTime
1364 *
1365 * DESCRIPTION: query exif date time
1366 *
1367 * PARAMETERS :
1368 * @dateTime : string to store exif date time
1369 * @count : lenght of the dateTime string
1370 *
1371 * RETURN : int32_t type of status
1372 * NO_ERROR -- success
1373 * none-zero failure code
1374 *==========================================================================*/
getExifDateTime(char * dateTime,uint32_t & count)1375 int32_t getExifDateTime(char *dateTime, uint32_t &count)
1376 {
1377 //get time and date from system
1378 time_t rawtime;
1379 struct tm * timeinfo;
1380 time(&rawtime);
1381 timeinfo = localtime (&rawtime);
1382 //Write datetime according to EXIF Spec
1383 //"YYYY:MM:DD HH:MM:SS" (20 chars including \0)
1384 snprintf(dateTime, 20, "%04d:%02d:%02d %02d:%02d:%02d",
1385 timeinfo->tm_year + 1900, timeinfo->tm_mon + 1,
1386 timeinfo->tm_mday, timeinfo->tm_hour,
1387 timeinfo->tm_min, timeinfo->tm_sec);
1388 count = 20;
1389
1390 return NO_ERROR;
1391 }
1392
1393 /*===========================================================================
1394 * FUNCTION : getExifFocalLength
1395 *
1396 * DESCRIPTION: get exif focal lenght
1397 *
1398 * PARAMETERS :
1399 * @focalLength : ptr to rational strcut to store focal lenght
1400 *
1401 * RETURN : int32_t type of status
1402 * NO_ERROR -- success
1403 * none-zero failure code
1404 *==========================================================================*/
getExifFocalLength(rat_t * focalLength,float value)1405 int32_t getExifFocalLength(rat_t *focalLength, float value)
1406 {
1407 int focalLengthValue =
1408 (int)(value * FOCAL_LENGTH_DECIMAL_PRECISION);
1409 return getRational(focalLength, focalLengthValue, FOCAL_LENGTH_DECIMAL_PRECISION);
1410 }
1411
1412 /*===========================================================================
1413 * FUNCTION : getExifExpTimeInfo
1414 *
1415 * DESCRIPTION: get exif exposure time information
1416 *
1417 * PARAMETERS :
1418 * @expoTimeInfo : expousure time value
1419 * RETURN : nt32_t type of status
1420 * NO_ERROR -- success
1421 * none-zero failure code
1422 *==========================================================================*/
getExifExpTimeInfo(rat_t * expoTimeInfo,int64_t value)1423 int32_t getExifExpTimeInfo(rat_t *expoTimeInfo, int64_t value)
1424 {
1425
1426 int cal_exposureTime;
1427 if (value != 0)
1428 cal_exposureTime = value;
1429 else
1430 cal_exposureTime = 60;
1431
1432 return getRational(expoTimeInfo, 1, cal_exposureTime);
1433 }
1434
1435 /*===========================================================================
1436 * FUNCTION : getExifGpsProcessingMethod
1437 *
1438 * DESCRIPTION: get GPS processing method
1439 *
1440 * PARAMETERS :
1441 * @gpsProcessingMethod : string to store GPS process method
1442 * @count : lenght of the string
1443 *
1444 * RETURN : int32_t type of status
1445 * NO_ERROR -- success
1446 * none-zero failure code
1447 *==========================================================================*/
getExifGpsProcessingMethod(char * gpsProcessingMethod,uint32_t & count,char * value)1448 int32_t getExifGpsProcessingMethod(char *gpsProcessingMethod,
1449 uint32_t &count, char* value)
1450 {
1451 if(value != NULL) {
1452 memcpy(gpsProcessingMethod, ExifAsciiPrefix, EXIF_ASCII_PREFIX_SIZE);
1453 count = EXIF_ASCII_PREFIX_SIZE;
1454 strncpy(gpsProcessingMethod + EXIF_ASCII_PREFIX_SIZE, value, strlen(value));
1455 count += strlen(value);
1456 gpsProcessingMethod[count++] = '\0'; // increase 1 for the last NULL char
1457 return NO_ERROR;
1458 } else {
1459 return BAD_VALUE;
1460 }
1461 }
1462
1463 /*===========================================================================
1464 * FUNCTION : getExifLatitude
1465 *
1466 * DESCRIPTION: get exif latitude
1467 *
1468 * PARAMETERS :
1469 * @latitude : ptr to rational struct to store latitude info
1470 * @ladRef : charater to indicate latitude reference
1471 *
1472 * RETURN : int32_t type of status
1473 * NO_ERROR -- success
1474 * none-zero failure code
1475 *==========================================================================*/
getExifLatitude(rat_t * latitude,char * latRef,double value)1476 int32_t getExifLatitude(rat_t *latitude,
1477 char *latRef, double value)
1478 {
1479 char str[30];
1480 snprintf(str, sizeof(str), "%f", value);
1481 if(str != NULL) {
1482 parseGPSCoordinate(str, latitude);
1483
1484 //set Latitude Ref
1485 float latitudeValue = strtof(str, 0);
1486 if(latitudeValue < 0.0f) {
1487 latRef[0] = 'S';
1488 } else {
1489 latRef[0] = 'N';
1490 }
1491 latRef[1] = '\0';
1492 return NO_ERROR;
1493 }else{
1494 return BAD_VALUE;
1495 }
1496 }
1497
1498 /*===========================================================================
1499 * FUNCTION : getExifLongitude
1500 *
1501 * DESCRIPTION: get exif longitude
1502 *
1503 * PARAMETERS :
1504 * @longitude : ptr to rational struct to store longitude info
1505 * @lonRef : charater to indicate longitude reference
1506 *
1507 * RETURN : int32_t type of status
1508 * NO_ERROR -- success
1509 * none-zero failure code
1510 *==========================================================================*/
getExifLongitude(rat_t * longitude,char * lonRef,double value)1511 int32_t getExifLongitude(rat_t *longitude,
1512 char *lonRef, double value)
1513 {
1514 char str[30];
1515 snprintf(str, sizeof(str), "%f", value);
1516 if(str != NULL) {
1517 parseGPSCoordinate(str, longitude);
1518
1519 //set Longitude Ref
1520 float longitudeValue = strtof(str, 0);
1521 if(longitudeValue < 0.0f) {
1522 lonRef[0] = 'W';
1523 } else {
1524 lonRef[0] = 'E';
1525 }
1526 lonRef[1] = '\0';
1527 return NO_ERROR;
1528 }else{
1529 return BAD_VALUE;
1530 }
1531 }
1532
1533 /*===========================================================================
1534 * FUNCTION : getExifAltitude
1535 *
1536 * DESCRIPTION: get exif altitude
1537 *
1538 * PARAMETERS :
1539 * @altitude : ptr to rational struct to store altitude info
1540 * @altRef : charater to indicate altitude reference
1541 *
1542 * RETURN : int32_t type of status
1543 * NO_ERROR -- success
1544 * none-zero failure code
1545 *==========================================================================*/
getExifAltitude(rat_t * altitude,char * altRef,double value)1546 int32_t getExifAltitude(rat_t *altitude,
1547 char *altRef, double value)
1548 {
1549 char str[30];
1550 snprintf(str, sizeof(str), "%f", value);
1551 if(str != NULL) {
1552 double value = atof(str);
1553 *altRef = 0;
1554 if(value < 0){
1555 *altRef = 1;
1556 value = -value;
1557 }
1558 return getRational(altitude, value*1000, 1000);
1559 }else{
1560 return BAD_VALUE;
1561 }
1562 }
1563
1564 /*===========================================================================
1565 * FUNCTION : getExifGpsDateTimeStamp
1566 *
1567 * DESCRIPTION: get exif GPS date time stamp
1568 *
1569 * PARAMETERS :
1570 * @gpsDateStamp : GPS date time stamp string
1571 * @bufLen : length of the string
1572 * @gpsTimeStamp : ptr to rational struct to store time stamp info
1573 *
1574 * RETURN : int32_t type of status
1575 * NO_ERROR -- success
1576 * none-zero failure code
1577 *==========================================================================*/
getExifGpsDateTimeStamp(char * gpsDateStamp,uint32_t bufLen,rat_t * gpsTimeStamp,int64_t value)1578 int32_t getExifGpsDateTimeStamp(char *gpsDateStamp,
1579 uint32_t bufLen,
1580 rat_t *gpsTimeStamp, int64_t value)
1581 {
1582 char str[30];
1583 snprintf(str, sizeof(str), "%lld", value);
1584 if(str != NULL) {
1585 time_t unixTime = (time_t)atol(str);
1586 struct tm *UTCTimestamp = gmtime(&unixTime);
1587
1588 strftime(gpsDateStamp, bufLen, "%Y:%m:%d", UTCTimestamp);
1589
1590 getRational(&gpsTimeStamp[0], UTCTimestamp->tm_hour, 1);
1591 getRational(&gpsTimeStamp[1], UTCTimestamp->tm_min, 1);
1592 getRational(&gpsTimeStamp[2], UTCTimestamp->tm_sec, 1);
1593
1594 return NO_ERROR;
1595 } else {
1596 return BAD_VALUE;
1597 }
1598 }
1599
getExifExposureValue(srat_t * exposure_val,int32_t exposure_comp,cam_rational_type_t step)1600 int32_t getExifExposureValue(srat_t* exposure_val, int32_t exposure_comp,
1601 cam_rational_type_t step)
1602 {
1603 exposure_val->num = exposure_comp * step.numerator;
1604 exposure_val->denom = step.denominator;
1605 return 0;
1606 }
1607 /*===========================================================================
1608 * FUNCTION : getExifData
1609 *
1610 * DESCRIPTION: get exif data to be passed into jpeg encoding
1611 *
1612 * PARAMETERS : none
1613 *
1614 * RETURN : exif data from user setting and GPS
1615 *==========================================================================*/
getExifData()1616 QCamera3Exif *QCamera3PicChannel::getExifData()
1617 {
1618 QCamera3Exif *exif = new QCamera3Exif();
1619 if (exif == NULL) {
1620 ALOGE("%s: No memory for QCamera3Exif", __func__);
1621 return NULL;
1622 }
1623
1624 int32_t rc = NO_ERROR;
1625 uint32_t count = 0;
1626
1627 // add exif entries
1628 char dateTime[20];
1629 memset(dateTime, 0, sizeof(dateTime));
1630 count = 20;
1631 rc = getExifDateTime(dateTime, count);
1632 if(rc == NO_ERROR) {
1633 exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL,
1634 EXIF_ASCII,
1635 count,
1636 (void *)dateTime);
1637 exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_DIGITIZED,
1638 EXIF_ASCII,
1639 count,
1640 (void *)dateTime);
1641 } else {
1642 ALOGE("%s: getExifDateTime failed", __func__);
1643 }
1644
1645 rat_t focalLength;
1646 rc = getExifFocalLength(&focalLength, mJpegSettings->lens_focal_length);
1647 if (rc == NO_ERROR) {
1648 exif->addEntry(EXIFTAGID_FOCAL_LENGTH,
1649 EXIF_RATIONAL,
1650 1,
1651 (void *)&(focalLength));
1652 } else {
1653 ALOGE("%s: getExifFocalLength failed", __func__);
1654 }
1655
1656 uint16_t isoSpeed = (uint16_t)mJpegSettings->sensor_sensitivity;
1657 exif->addEntry(EXIFTAGID_ISO_SPEED_RATING,
1658 EXIF_SHORT,
1659 1,
1660 (void *)&(isoSpeed));
1661
1662 rat_t sensorExpTime ;
1663 rc = getExifExpTimeInfo(&sensorExpTime, (int64_t)mJpegSettings->sensor_exposure_time);
1664 if (rc == NO_ERROR){
1665 exif->addEntry(EXIFTAGID_EXPOSURE_TIME,
1666 EXIF_RATIONAL,
1667 1,
1668 (void *)&(sensorExpTime));
1669 } else {
1670 ALOGE("%s: getExifExpTimeInfo failed", __func__);
1671 }
1672
1673 if (strlen(mJpegSettings->gps_processing_method) > 0) {
1674 char gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE];
1675 count = 0;
1676 rc = getExifGpsProcessingMethod(gpsProcessingMethod, count, mJpegSettings->gps_processing_method);
1677 if(rc == NO_ERROR) {
1678 exif->addEntry(EXIFTAGID_GPS_PROCESSINGMETHOD,
1679 EXIF_ASCII,
1680 count,
1681 (void *)gpsProcessingMethod);
1682 } else {
1683 ALOGE("%s: getExifGpsProcessingMethod failed", __func__);
1684 }
1685 }
1686
1687 if (mJpegSettings->gps_coordinates[0]) {
1688 rat_t latitude[3];
1689 char latRef[2];
1690 rc = getExifLatitude(latitude, latRef, *(mJpegSettings->gps_coordinates[0]));
1691 if(rc == NO_ERROR) {
1692 exif->addEntry(EXIFTAGID_GPS_LATITUDE,
1693 EXIF_RATIONAL,
1694 3,
1695 (void *)latitude);
1696 exif->addEntry(EXIFTAGID_GPS_LATITUDE_REF,
1697 EXIF_ASCII,
1698 2,
1699 (void *)latRef);
1700 } else {
1701 ALOGE("%s: getExifLatitude failed", __func__);
1702 }
1703 }
1704
1705 if (mJpegSettings->gps_coordinates[1]) {
1706 rat_t longitude[3];
1707 char lonRef[2];
1708 rc = getExifLongitude(longitude, lonRef, *(mJpegSettings->gps_coordinates[1]));
1709 if(rc == NO_ERROR) {
1710 exif->addEntry(EXIFTAGID_GPS_LONGITUDE,
1711 EXIF_RATIONAL,
1712 3,
1713 (void *)longitude);
1714
1715 exif->addEntry(EXIFTAGID_GPS_LONGITUDE_REF,
1716 EXIF_ASCII,
1717 2,
1718 (void *)lonRef);
1719 } else {
1720 ALOGE("%s: getExifLongitude failed", __func__);
1721 }
1722 }
1723
1724 if (mJpegSettings->gps_coordinates[2]) {
1725 rat_t altitude;
1726 char altRef;
1727 rc = getExifAltitude(&altitude, &altRef, *(mJpegSettings->gps_coordinates[2]));
1728 if(rc == NO_ERROR) {
1729 exif->addEntry(EXIFTAGID_GPS_ALTITUDE,
1730 EXIF_RATIONAL,
1731 1,
1732 (void *)&(altitude));
1733
1734 exif->addEntry(EXIFTAGID_GPS_ALTITUDE_REF,
1735 EXIF_BYTE,
1736 1,
1737 (void *)&altRef);
1738 } else {
1739 ALOGE("%s: getExifAltitude failed", __func__);
1740 }
1741 }
1742
1743 if (mJpegSettings->gps_timestamp) {
1744 char gpsDateStamp[20];
1745 rat_t gpsTimeStamp[3];
1746 rc = getExifGpsDateTimeStamp(gpsDateStamp, 20, gpsTimeStamp, *(mJpegSettings->gps_timestamp));
1747 if(rc == NO_ERROR) {
1748 exif->addEntry(EXIFTAGID_GPS_DATESTAMP,
1749 EXIF_ASCII,
1750 strlen(gpsDateStamp) + 1,
1751 (void *)gpsDateStamp);
1752
1753 exif->addEntry(EXIFTAGID_GPS_TIMESTAMP,
1754 EXIF_RATIONAL,
1755 3,
1756 (void *)gpsTimeStamp);
1757 } else {
1758 ALOGE("%s: getExifGpsDataTimeStamp failed", __func__);
1759 }
1760 }
1761
1762 srat_t exposure_val;
1763 rc = getExifExposureValue(&exposure_val, mJpegSettings->exposure_compensation,
1764 mJpegSettings->exposure_comp_step);
1765 if(rc == NO_ERROR) {
1766 exif->addEntry(EXIFTAGID_EXPOSURE_BIAS_VALUE,
1767 EXIF_SRATIONAL,
1768 1,
1769 (void *)(&exposure_val));
1770 } else {
1771 ALOGE("%s: getExifExposureValue failed ", __func__);
1772 }
1773
1774 char value[PROPERTY_VALUE_MAX];
1775 if (property_get("ro.product.manufacturer", value, "QCOM-AA") > 0) {
1776 exif->addEntry(EXIFTAGID_MAKE,
1777 EXIF_ASCII,
1778 strlen(value) + 1,
1779 (void *)value);
1780 } else {
1781 ALOGE("%s: getExifMaker failed", __func__);
1782 }
1783
1784 if (property_get("ro.product.model", value, "QCAM-AA") > 0) {
1785 exif->addEntry(EXIFTAGID_MODEL,
1786 EXIF_ASCII,
1787 strlen(value) + 1,
1788 (void *)value);
1789 } else {
1790 ALOGE("%s: getExifModel failed", __func__);
1791 }
1792
1793 return exif;
1794 }
1795
1796 int QCamera3PicChannel::kMaxBuffers = 2;
1797
1798 /*===========================================================================
1799 * FUNCTION : QCamera3ReprocessChannel
1800 *
1801 * DESCRIPTION: constructor of QCamera3ReprocessChannel
1802 *
1803 * PARAMETERS :
1804 * @cam_handle : camera handle
1805 * @cam_ops : ptr to camera ops table
1806 * @pp_mask : post-proccess feature mask
1807 *
1808 * RETURN : none
1809 *==========================================================================*/
QCamera3ReprocessChannel(uint32_t cam_handle,mm_camera_ops_t * cam_ops,channel_cb_routine cb_routine,cam_padding_info_t * paddingInfo,void * userData,void * ch_hdl)1810 QCamera3ReprocessChannel::QCamera3ReprocessChannel(uint32_t cam_handle,
1811 mm_camera_ops_t *cam_ops,
1812 channel_cb_routine cb_routine,
1813 cam_padding_info_t *paddingInfo,
1814 void *userData, void *ch_hdl) :
1815 QCamera3Channel(cam_handle, cam_ops, cb_routine, paddingInfo, userData),
1816 picChHandle(ch_hdl),
1817 m_pSrcChannel(NULL),
1818 m_pMetaChannel(NULL),
1819 mMemory(NULL)
1820 {
1821 memset(mSrcStreamHandles, 0, sizeof(mSrcStreamHandles));
1822 }
1823
1824
1825 /*===========================================================================
1826 * FUNCTION : QCamera3ReprocessChannel
1827 *
1828 * DESCRIPTION: constructor of QCamera3ReprocessChannel
1829 *
1830 * PARAMETERS :
1831 * @cam_handle : camera handle
1832 * @cam_ops : ptr to camera ops table
1833 * @pp_mask : post-proccess feature mask
1834 *
1835 * RETURN : none
1836 *==========================================================================*/
initialize()1837 int32_t QCamera3ReprocessChannel::initialize()
1838 {
1839 int32_t rc = NO_ERROR;
1840 mm_camera_channel_attr_t attr;
1841
1842 memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
1843 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
1844 attr.max_unmatched_frames = 1;
1845
1846 rc = init(&attr, NULL);
1847 if (rc < 0) {
1848 ALOGE("%s: init failed", __func__);
1849 }
1850 return rc;
1851 }
1852
1853
1854 /*===========================================================================
1855 * FUNCTION : QCamera3ReprocessChannel
1856 *
1857 * DESCRIPTION: constructor of QCamera3ReprocessChannel
1858 *
1859 * PARAMETERS :
1860 * @cam_handle : camera handle
1861 * @cam_ops : ptr to camera ops table
1862 * @pp_mask : post-proccess feature mask
1863 *
1864 * RETURN : none
1865 *==========================================================================*/
streamCbRoutine(mm_camera_super_buf_t * super_frame,QCamera3Stream * stream)1866 void QCamera3ReprocessChannel::streamCbRoutine(mm_camera_super_buf_t *super_frame,
1867 QCamera3Stream *stream)
1868 {
1869 //Got the pproc data callback. Now send to jpeg encoding
1870 uint8_t frameIndex;
1871 mm_camera_super_buf_t* frame = NULL;
1872 QCamera3PicChannel *obj = (QCamera3PicChannel *)picChHandle;
1873
1874 if(!super_frame) {
1875 ALOGE("%s: Invalid Super buffer",__func__);
1876 return;
1877 }
1878
1879 if(super_frame->num_bufs != 1) {
1880 ALOGE("%s: Multiple streams are not supported",__func__);
1881 return;
1882 }
1883 if(super_frame->bufs[0] == NULL ) {
1884 ALOGE("%s: Error, Super buffer frame does not contain valid buffer",
1885 __func__);
1886 return;
1887 }
1888
1889 frameIndex = (uint8_t)super_frame->bufs[0]->buf_idx;
1890 frame = (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t));
1891 if (frame == NULL) {
1892 ALOGE("%s: Error allocating memory to save received_frame structure.",
1893 __func__);
1894 if(stream) {
1895 stream->bufDone(frameIndex);
1896 }
1897 return;
1898 }
1899 *frame = *super_frame;
1900 obj->m_postprocessor.processPPData(frame);
1901 return;
1902 }
1903
1904 /*===========================================================================
1905 * FUNCTION : QCamera3ReprocessChannel
1906 *
1907 * DESCRIPTION: default constructor of QCamera3ReprocessChannel
1908 *
1909 * PARAMETERS : none
1910 *
1911 * RETURN : none
1912 *==========================================================================*/
QCamera3ReprocessChannel()1913 QCamera3ReprocessChannel::QCamera3ReprocessChannel() :
1914 m_pSrcChannel(NULL),
1915 m_pMetaChannel(NULL)
1916 {
1917 }
1918
1919 /*===========================================================================
1920 * FUNCTION : QCamera3ReprocessChannel
1921 *
1922 * DESCRIPTION: register the buffers of the reprocess channel
1923 *
1924 * PARAMETERS : none
1925 *
1926 * RETURN : none
1927 *==========================================================================*/
registerBuffers(uint32_t,buffer_handle_t **)1928 int32_t QCamera3ReprocessChannel::registerBuffers(
1929 uint32_t /*num_buffers*/, buffer_handle_t ** /*buffers*/)
1930 {
1931 return 0;
1932 }
1933
1934 /*===========================================================================
1935 * FUNCTION : getStreamBufs
1936 *
1937 * DESCRIPTION: register the buffers of the reprocess channel
1938 *
1939 * PARAMETERS : none
1940 *
1941 * RETURN : QCamera3Memory *
1942 *==========================================================================*/
getStreamBufs(uint32_t len)1943 QCamera3Memory* QCamera3ReprocessChannel::getStreamBufs(uint32_t len)
1944 {
1945 int rc = 0;
1946
1947 mMemory = new QCamera3HeapMemory();
1948 if (!mMemory) {
1949 ALOGE("%s: unable to create reproc memory", __func__);
1950 return NULL;
1951 }
1952
1953 //Queue YUV buffers in the beginning mQueueAll = true
1954 rc = mMemory->allocate(2, len, true);
1955 if (rc < 0) {
1956 ALOGE("%s: unable to allocate reproc memory", __func__);
1957 delete mMemory;
1958 mMemory = NULL;
1959 return NULL;
1960 }
1961 return mMemory;
1962 }
1963
1964 /*===========================================================================
1965 * FUNCTION : getStreamBufs
1966 *
1967 * DESCRIPTION: register the buffers of the reprocess channel
1968 *
1969 * PARAMETERS : none
1970 *
1971 * RETURN :
1972 *==========================================================================*/
putStreamBufs()1973 void QCamera3ReprocessChannel::putStreamBufs()
1974 {
1975 mMemory->deallocate();
1976 delete mMemory;
1977 mMemory = NULL;
1978 }
1979
1980 /*===========================================================================
1981 * FUNCTION : ~QCamera3ReprocessChannel
1982 *
1983 * DESCRIPTION: destructor of QCamera3ReprocessChannel
1984 *
1985 * PARAMETERS : none
1986 *
1987 * RETURN : none
1988 *==========================================================================*/
~QCamera3ReprocessChannel()1989 QCamera3ReprocessChannel::~QCamera3ReprocessChannel()
1990 {
1991 }
1992
1993 /*===========================================================================
1994 * FUNCTION : getStreamBySourceHandle
1995 *
1996 * DESCRIPTION: find reprocess stream by its source stream handle
1997 *
1998 * PARAMETERS :
1999 * @srcHandle : source stream handle
2000 *
2001 * RETURN : ptr to reprocess stream if found. NULL if not found
2002 *==========================================================================*/
getStreamBySourceHandle(uint32_t srcHandle)2003 QCamera3Stream * QCamera3ReprocessChannel::getStreamBySourceHandle(uint32_t srcHandle)
2004 {
2005 QCamera3Stream *pStream = NULL;
2006
2007 for (int i = 0; i < m_numStreams; i++) {
2008 if (mSrcStreamHandles[i] == srcHandle) {
2009 pStream = mStreams[i];
2010 break;
2011 }
2012 }
2013 return pStream;
2014 }
2015
2016 /*===========================================================================
2017 * FUNCTION : metadataBufDone
2018 *
2019 * DESCRIPTION: buf done method for a metadata buffer
2020 *
2021 * PARAMETERS :
2022 * @recvd_frame : received metadata frame
2023 *
2024 * RETURN :
2025 *==========================================================================*/
metadataBufDone(mm_camera_super_buf_t * recvd_frame)2026 int32_t QCamera3ReprocessChannel::metadataBufDone(mm_camera_super_buf_t *recvd_frame)
2027 {
2028 int32_t rc;
2029 rc = ((QCamera3MetadataChannel*)m_pMetaChannel)->bufDone(recvd_frame);
2030 free(recvd_frame);
2031 recvd_frame = NULL;
2032 return rc;
2033 }
2034
2035 /*===========================================================================
2036 * FUNCTION : doReprocess
2037 *
2038 * DESCRIPTION: request to do a reprocess on the frame
2039 *
2040 * PARAMETERS :
2041 * @frame : frame to be performed a reprocess
2042 *
2043 * RETURN : int32_t type of status
2044 * NO_ERROR -- success
2045 * none-zero failure code
2046 *==========================================================================*/
doReprocess(mm_camera_super_buf_t * frame,mm_camera_super_buf_t * meta_frame)2047 int32_t QCamera3ReprocessChannel::doReprocess(mm_camera_super_buf_t *frame,
2048 mm_camera_super_buf_t *meta_frame)
2049 {
2050 int32_t rc = 0;
2051 if (m_numStreams < 1) {
2052 ALOGE("%s: No reprocess stream is created", __func__);
2053 return -1;
2054 }
2055 if (m_pSrcChannel == NULL) {
2056 ALOGE("%s: No source channel for reprocess", __func__);
2057 return -1;
2058 }
2059 for (int i = 0; i < frame->num_bufs; i++) {
2060 QCamera3Stream *pStream = getStreamBySourceHandle(frame->bufs[i]->stream_id);
2061 if (pStream != NULL) {
2062 cam_stream_parm_buffer_t param;
2063 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t));
2064 param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS;
2065 param.reprocess.buf_index = frame->bufs[i]->buf_idx;
2066 param.reprocess.frame_idx = frame->bufs[i]->frame_idx;
2067 if (meta_frame != NULL) {
2068 param.reprocess.meta_present = 1;
2069 param.reprocess.meta_stream_handle = m_pMetaChannel->mStreams[0]->getMyServerID();
2070 param.reprocess.meta_buf_index = meta_frame->bufs[0]->buf_idx;
2071 }
2072 rc = pStream->setParameter(param);
2073 if (rc != NO_ERROR) {
2074 ALOGE("%s: stream setParameter for reprocess failed", __func__);
2075 break;
2076 }
2077 }
2078 }
2079 return rc;
2080 }
2081
2082 /*===========================================================================
2083 * FUNCTION : doReprocess
2084 *
2085 * DESCRIPTION: request to do a reprocess on the frame
2086 *
2087 * PARAMETERS :
2088 * @buf_fd : fd to the input buffer that needs reprocess
2089 * @buf_lenght : length of the input buffer
2090 * @ret_val : result of reprocess.
2091 * Example: Could be faceID in case of register face image.
2092 *
2093 * RETURN : int32_t type of status
2094 * NO_ERROR -- success
2095 * none-zero failure code
2096 *==========================================================================*/
doReprocess(int buf_fd,uint32_t buf_length,int32_t & ret_val,mm_camera_super_buf_t * meta_frame)2097 int32_t QCamera3ReprocessChannel::doReprocess(int buf_fd,
2098 uint32_t buf_length,
2099 int32_t &ret_val,
2100 mm_camera_super_buf_t *meta_frame)
2101 {
2102 int32_t rc = 0;
2103 if (m_numStreams < 1) {
2104 ALOGE("%s: No reprocess stream is created", __func__);
2105 return -1;
2106 }
2107 if (meta_frame == NULL) {
2108 ALOGE("%s: Did not get corresponding metadata in time", __func__);
2109 return -1;
2110 }
2111
2112 uint32_t buf_idx = 0;
2113 for (int i = 0; i < m_numStreams; i++) {
2114 rc = mStreams[i]->mapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF,
2115 buf_idx, -1,
2116 buf_fd, buf_length);
2117
2118 if (rc == NO_ERROR) {
2119 cam_stream_parm_buffer_t param;
2120 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t));
2121 param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS;
2122 param.reprocess.buf_index = buf_idx;
2123 param.reprocess.meta_present = 1;
2124 param.reprocess.meta_stream_handle = m_pMetaChannel->mStreams[0]->getMyServerID();
2125 param.reprocess.meta_buf_index = meta_frame->bufs[0]->buf_idx;
2126 rc = mStreams[i]->setParameter(param);
2127 if (rc == NO_ERROR) {
2128 ret_val = param.reprocess.ret_val;
2129 }
2130 mStreams[i]->unmapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF,
2131 buf_idx, -1);
2132 }
2133 }
2134 return rc;
2135 }
2136
2137 /*===========================================================================
2138 * FUNCTION : addReprocStreamsFromSource
2139 *
2140 * DESCRIPTION: add reprocess streams from input source channel
2141 *
2142 * PARAMETERS :
2143 * @config : pp feature configuration
2144 * @pSrcChannel : ptr to input source channel that needs reprocess
2145 * @pMetaChannel : ptr to metadata channel to get corresp. metadata
2146 *
2147 * RETURN : int32_t type of status
2148 * NO_ERROR -- success
2149 * none-zero failure code
2150 *==========================================================================*/
addReprocStreamsFromSource(cam_pp_feature_config_t & config,QCamera3Channel * pSrcChannel,QCamera3Channel * pMetaChannel)2151 int32_t QCamera3ReprocessChannel::addReprocStreamsFromSource(cam_pp_feature_config_t &config,
2152 QCamera3Channel *pSrcChannel,
2153 QCamera3Channel *pMetaChannel)
2154 {
2155 int32_t rc = 0;
2156 QCamera3Stream *pSrcStream = pSrcChannel->getStreamByIndex(0);
2157 if (pSrcStream == NULL) {
2158 ALOGE("%s: source channel doesn't have a stream", __func__);
2159 return BAD_VALUE;
2160 }
2161 cam_stream_reproc_config_t reprocess_config;
2162 cam_dimension_t streamDim;
2163 cam_stream_type_t streamType;
2164 cam_format_t streamFormat;
2165 cam_frame_len_offset_t frameOffset;
2166 int num_buffers = 2;
2167
2168 streamType = CAM_STREAM_TYPE_OFFLINE_PROC;
2169 pSrcStream->getFormat(streamFormat);
2170 pSrcStream->getFrameDimension(streamDim);
2171 pSrcStream->getFrameOffset(frameOffset);
2172
2173 reprocess_config.pp_type = CAM_ONLINE_REPROCESS_TYPE;
2174 reprocess_config.online.input_stream_id = pSrcStream->getMyServerID();
2175 reprocess_config.online.input_stream_type = pSrcStream->getMyType();
2176 reprocess_config.pp_feature_config = config;
2177
2178 mSrcStreamHandles[m_numStreams] = pSrcStream->getMyHandle();
2179
2180 if (reprocess_config.pp_feature_config.feature_mask & CAM_QCOM_FEATURE_ROTATION) {
2181 if (reprocess_config.pp_feature_config.rotation == ROTATE_90 ||
2182 reprocess_config.pp_feature_config.rotation == ROTATE_270) {
2183 // rotated by 90 or 270, need to switch width and height
2184 int32_t temp = streamDim.height;
2185 streamDim.height = streamDim.width;
2186 streamDim.width = temp;
2187 }
2188 }
2189
2190 QCamera3Stream *pStream = new QCamera3Stream(m_camHandle,
2191 m_handle,
2192 m_camOps,
2193 mPaddingInfo,
2194 (QCamera3Channel*)this);
2195 if (pStream == NULL) {
2196 ALOGE("%s: No mem for Stream", __func__);
2197 return NO_MEMORY;
2198 }
2199
2200 rc = pStream->init(streamType, streamFormat, streamDim, &reprocess_config,
2201 num_buffers,QCamera3Channel::streamCbRoutine, this);
2202
2203
2204 if (rc == 0) {
2205 mStreams[m_numStreams] = pStream;
2206 m_numStreams++;
2207 } else {
2208 ALOGE("%s: failed to create reprocess stream", __func__);
2209 delete pStream;
2210 }
2211
2212 if (rc == NO_ERROR) {
2213 m_pSrcChannel = pSrcChannel;
2214 m_pMetaChannel = pMetaChannel;
2215 }
2216 if(m_camOps->request_super_buf(m_camHandle,m_handle,1) < 0) {
2217 ALOGE("%s: Request for super buffer failed",__func__);
2218 }
2219 return rc;
2220 }
2221
2222
2223 }; // namespace qcamera
2224