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