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 "QCamera3Stream"
31 //#define LOG_NDEBUG 0
32
33 #include <utils/Log.h>
34 #include <utils/Errors.h>
35 #include "QCamera3HWI.h"
36 #include "QCamera3Stream.h"
37 #include "QCamera3Channel.h"
38
39 using namespace android;
40
41 namespace qcamera {
42
43 /*===========================================================================
44 * FUNCTION : get_bufs
45 *
46 * DESCRIPTION: static function entry to allocate stream buffers
47 *
48 * PARAMETERS :
49 * @offset : offset info of stream buffers
50 * @num_bufs : number of buffers allocated
51 * @initial_reg_flag: flag to indicate if buffer needs to be registered
52 * at kernel initially
53 * @bufs : output of allocated buffers
54 * @ops_tbl : ptr to buf mapping/unmapping ops
55 * @user_data : user data ptr of ops_tbl
56 *
57 * RETURN : int32_t type of status
58 * NO_ERROR -- success
59 * none-zero failure code
60 *==========================================================================*/
get_bufs(cam_frame_len_offset_t * offset,uint8_t * num_bufs,uint8_t ** initial_reg_flag,mm_camera_buf_def_t ** bufs,mm_camera_map_unmap_ops_tbl_t * ops_tbl,void * user_data)61 int32_t QCamera3Stream::get_bufs(
62 cam_frame_len_offset_t *offset,
63 uint8_t *num_bufs,
64 uint8_t **initial_reg_flag,
65 mm_camera_buf_def_t **bufs,
66 mm_camera_map_unmap_ops_tbl_t *ops_tbl,
67 void *user_data)
68 {
69 QCamera3Stream *stream = reinterpret_cast<QCamera3Stream *>(user_data);
70 if (!stream) {
71 ALOGE("getBufs invalid stream pointer");
72 return NO_MEMORY;
73 }
74 return stream->getBufs(offset, num_bufs, initial_reg_flag, bufs, ops_tbl);
75 }
76
77 /*===========================================================================
78 * FUNCTION : put_bufs
79 *
80 * DESCRIPTION: static function entry to deallocate stream buffers
81 *
82 * PARAMETERS :
83 * @ops_tbl : ptr to buf mapping/unmapping ops
84 * @user_data : user data ptr of ops_tbl
85 *
86 * RETURN : int32_t type of status
87 * NO_ERROR -- success
88 * none-zero failure code
89 *==========================================================================*/
put_bufs(mm_camera_map_unmap_ops_tbl_t * ops_tbl,void * user_data)90 int32_t QCamera3Stream::put_bufs(
91 mm_camera_map_unmap_ops_tbl_t *ops_tbl,
92 void *user_data)
93 {
94 QCamera3Stream *stream = reinterpret_cast<QCamera3Stream *>(user_data);
95 if (!stream) {
96 ALOGE("putBufs invalid stream pointer");
97 return NO_MEMORY;
98 }
99 return stream->putBufs(ops_tbl);
100 }
101
102 /*===========================================================================
103 * FUNCTION : invalidate_buf
104 *
105 * DESCRIPTION: static function entry to invalidate a specific stream buffer
106 *
107 * PARAMETERS :
108 * @index : index of the stream buffer to invalidate
109 * @user_data : user data ptr of ops_tbl
110 *
111 * RETURN : int32_t type of status
112 * NO_ERROR -- success
113 * none-zero failure code
114 *==========================================================================*/
invalidate_buf(int index,void * user_data)115 int32_t QCamera3Stream::invalidate_buf(int index, void *user_data)
116 {
117 QCamera3Stream *stream = reinterpret_cast<QCamera3Stream *>(user_data);
118 if (!stream) {
119 ALOGE("invalid stream pointer");
120 return NO_MEMORY;
121 }
122 return stream->invalidateBuf(index);
123 }
124
125 /*===========================================================================
126 * FUNCTION : clean_invalidate_buf
127 *
128 * DESCRIPTION: static function entry to clean and invalidate a specific stream buffer
129 *
130 * PARAMETERS :
131 * @index : index of the stream buffer to invalidate
132 * @user_data : user data ptr of ops_tbl
133 *
134 * RETURN : int32_t type of status
135 * NO_ERROR -- success
136 * none-zero failure code
137 *==========================================================================*/
clean_invalidate_buf(int index,void * user_data)138 int32_t QCamera3Stream::clean_invalidate_buf(int index, void *user_data)
139 {
140 QCamera3Stream *stream = reinterpret_cast<QCamera3Stream *>(user_data);
141 if (!stream) {
142 ALOGE("invalid stream pointer");
143 return NO_MEMORY;
144 }
145 return stream->cleanInvalidateBuf(index);
146 }
147
148 /*===========================================================================
149 * FUNCTION : QCamera3Stream
150 *
151 * DESCRIPTION: constructor of QCamera3Stream
152 *
153 * PARAMETERS :
154 * @allocator : memory allocator obj
155 * @camHandle : camera handle
156 * @chId : channel handle
157 * @camOps : ptr to camera ops table
158 * @paddingInfo: ptr to padding info
159 *
160 * RETURN : None
161 *==========================================================================*/
QCamera3Stream(uint32_t camHandle,uint32_t chId,mm_camera_ops_t * camOps,cam_padding_info_t * paddingInfo,QCamera3Channel * channel)162 QCamera3Stream::QCamera3Stream(uint32_t camHandle,
163 uint32_t chId,
164 mm_camera_ops_t *camOps,
165 cam_padding_info_t *paddingInfo,
166 QCamera3Channel *channel) :
167 mCamHandle(camHandle),
168 mChannelHandle(chId),
169 mHandle(0),
170 mCamOps(camOps),
171 mStreamInfo(NULL),
172 mMemOps(NULL),
173 mNumBufs(0),
174 mDataCB(NULL),
175 mUserData(NULL),
176 mDataQ(releaseFrameData, this),
177 mStreamInfoBuf(NULL),
178 mStreamBufs(NULL),
179 mBufDefs(NULL),
180 mChannel(channel),
181 m_bActive(false)
182 {
183 mMemVtbl.user_data = this;
184 mMemVtbl.get_bufs = get_bufs;
185 mMemVtbl.put_bufs = put_bufs;
186 mMemVtbl.invalidate_buf = invalidate_buf;
187 mMemVtbl.clean_invalidate_buf = clean_invalidate_buf;
188 memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
189 memcpy(&mPaddingInfo, paddingInfo, sizeof(cam_padding_info_t));
190 }
191
192 /*===========================================================================
193 * FUNCTION : ~QCamera3Stream
194 *
195 * DESCRIPTION: deconstructor of QCamera3Stream
196 *
197 * PARAMETERS : None
198 *
199 * RETURN : None
200 *==========================================================================*/
~QCamera3Stream()201 QCamera3Stream::~QCamera3Stream()
202 {
203 if (mStreamInfoBuf != NULL) {
204 int rc = mCamOps->unmap_stream_buf(mCamHandle,
205 mChannelHandle, mHandle, CAM_MAPPING_BUF_TYPE_STREAM_INFO, 0, -1);
206 if (rc < 0) {
207 ALOGE("Failed to map stream info buffer");
208 }
209 mStreamInfoBuf->deallocate();
210 delete mStreamInfoBuf;
211 mStreamInfoBuf = NULL;
212 }
213
214 // delete stream
215 if (mHandle > 0) {
216 mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle);
217 mHandle = 0;
218 }
219 }
220
221 /*===========================================================================
222 * FUNCTION : init
223 *
224 * DESCRIPTION: initialize stream obj
225 *
226 * PARAMETERS :
227 * @streamInfoBuf: ptr to buf that contains stream info
228 * @stream_cb : stream data notify callback. Can be NULL if not needed
229 * @userdata : user data ptr
230 *
231 * RETURN : int32_t type of status
232 * NO_ERROR -- success
233 * none-zero failure code
234 *==========================================================================*/
init(cam_stream_type_t streamType,cam_format_t streamFormat,cam_dimension_t streamDim,cam_stream_reproc_config_t * reprocess_config,uint8_t minNumBuffers,stream_cb_routine stream_cb,void * userdata)235 int32_t QCamera3Stream::init(cam_stream_type_t streamType,
236 cam_format_t streamFormat,
237 cam_dimension_t streamDim,
238 cam_stream_reproc_config_t* reprocess_config,
239 uint8_t minNumBuffers,
240 stream_cb_routine stream_cb,
241 void *userdata)
242 {
243 int32_t rc = OK;
244 mm_camera_stream_config_t stream_config;
245
246 mHandle = mCamOps->add_stream(mCamHandle, mChannelHandle);
247 if (!mHandle) {
248 ALOGE("add_stream failed");
249 rc = UNKNOWN_ERROR;
250 goto done;
251 }
252
253 // allocate and map stream info memory
254 mStreamInfoBuf = new QCamera3HeapMemory();
255 if (mStreamInfoBuf == NULL) {
256 ALOGE("%s: no memory for stream info buf obj", __func__);
257 rc = -ENOMEM;
258 goto err1;
259 }
260 rc = mStreamInfoBuf->allocate(1, sizeof(cam_stream_info_t), false);
261 if (rc < 0) {
262 ALOGE("%s: no memory for stream info", __func__);
263 rc = -ENOMEM;
264 goto err2;
265 }
266
267 mStreamInfo =
268 reinterpret_cast<cam_stream_info_t *>(mStreamInfoBuf->getPtr(0));
269 memset(mStreamInfo, 0, sizeof(cam_stream_info_t));
270 mStreamInfo->stream_type = streamType;
271 mStreamInfo->fmt = streamFormat;
272 mStreamInfo->dim = streamDim;
273 mStreamInfo->num_bufs = minNumBuffers;
274
275 rc = mCamOps->map_stream_buf(mCamHandle,
276 mChannelHandle, mHandle, CAM_MAPPING_BUF_TYPE_STREAM_INFO,
277 0, -1, mStreamInfoBuf->getFd(0), mStreamInfoBuf->getSize(0));
278 if (rc < 0) {
279 ALOGE("Failed to map stream info buffer");
280 goto err3;
281 }
282
283 mNumBufs = minNumBuffers;
284 if (reprocess_config != NULL) {
285 mStreamInfo->reprocess_config = *reprocess_config;
286 mStreamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
287 //mStreamInfo->num_of_burst = reprocess_config->offline.num_of_bufs;
288 mStreamInfo->num_of_burst = 1;
289 ALOGI("%s: num_of_burst is %d", __func__, mStreamInfo->num_of_burst);
290 } else {
291 mStreamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
292 }
293
294 // Configure the stream
295 stream_config.stream_info = mStreamInfo;
296 stream_config.mem_vtbl = mMemVtbl;
297 stream_config.padding_info = mPaddingInfo;
298 stream_config.userdata = this;
299 stream_config.stream_cb = dataNotifyCB;
300
301 rc = mCamOps->config_stream(mCamHandle,
302 mChannelHandle, mHandle, &stream_config);
303 if (rc < 0) {
304 ALOGE("Failed to config stream, rc = %d", rc);
305 goto err4;
306 }
307
308 mDataCB = stream_cb;
309 mUserData = userdata;
310 return 0;
311
312 err4:
313 mCamOps->unmap_stream_buf(mCamHandle,
314 mChannelHandle, mHandle, CAM_MAPPING_BUF_TYPE_STREAM_INFO, 0, -1);
315 err3:
316 mStreamInfoBuf->deallocate();
317 err2:
318 delete mStreamInfoBuf;
319 mStreamInfoBuf = NULL;
320 mStreamInfo = NULL;
321 err1:
322 mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle);
323 mHandle = 0;
324 mNumBufs = 0;
325 done:
326 return rc;
327 }
328
329 /*===========================================================================
330 * FUNCTION : start
331 *
332 * DESCRIPTION: start stream. Will start main stream thread to handle stream
333 * related ops.
334 *
335 * PARAMETERS : none
336 *
337 * RETURN : int32_t type of status
338 * NO_ERROR -- success
339 * none-zero failure code
340 *==========================================================================*/
start()341 int32_t QCamera3Stream::start()
342 {
343 int32_t rc = 0;
344 rc = mProcTh.launch(dataProcRoutine, this);
345 if (rc == NO_ERROR) {
346 m_bActive = true;
347 }
348 return rc;
349 }
350
351 /*===========================================================================
352 * FUNCTION : stop
353 *
354 * DESCRIPTION: stop stream. Will stop main stream thread
355 *
356 * PARAMETERS : none
357 *
358 * RETURN : int32_t type of status
359 * NO_ERROR -- success
360 * none-zero failure code
361 *==========================================================================*/
stop()362 int32_t QCamera3Stream::stop()
363 {
364 int32_t rc = 0;
365 rc = mProcTh.exit();
366 m_bActive = false;
367 return rc;
368 }
369
370 /*===========================================================================
371 * FUNCTION : processDataNotify
372 *
373 * DESCRIPTION: process stream data notify
374 *
375 * PARAMETERS :
376 * @frame : stream frame received
377 *
378 * RETURN : int32_t type of status
379 * NO_ERROR -- success
380 * none-zero failure code
381 *==========================================================================*/
processDataNotify(mm_camera_super_buf_t * frame)382 int32_t QCamera3Stream::processDataNotify(mm_camera_super_buf_t *frame)
383 {
384 ALOGV("%s: E\n", __func__);
385 int32_t rc;
386 if (m_bActive) {
387 mDataQ.enqueue((void *)frame);
388 rc = mProcTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE);
389 } else {
390 ALOGD("%s: Stream thread is not active, no ops here", __func__);
391 bufDone(frame->bufs[0]->buf_idx);
392 free(frame);
393 rc = NO_ERROR;
394 }
395 ALOGV("%s: X\n", __func__);
396 return rc;
397 }
398
399 /*===========================================================================
400 * FUNCTION : dataNotifyCB
401 *
402 * DESCRIPTION: callback for data notify. This function is registered with
403 * mm-camera-interface to handle data notify
404 *
405 * PARAMETERS :
406 * @recvd_frame : stream frame received
407 * userdata : user data ptr
408 *
409 * RETURN : none
410 *==========================================================================*/
dataNotifyCB(mm_camera_super_buf_t * recvd_frame,void * userdata)411 void QCamera3Stream::dataNotifyCB(mm_camera_super_buf_t *recvd_frame,
412 void *userdata)
413 {
414 ALOGV("%s: E\n", __func__);
415 QCamera3Stream* stream = (QCamera3Stream *)userdata;
416 if (stream == NULL ||
417 recvd_frame == NULL ||
418 recvd_frame->bufs[0] == NULL ||
419 recvd_frame->bufs[0]->stream_id != stream->getMyHandle()) {
420 ALOGE("%s: Not a valid stream to handle buf", __func__);
421 return;
422 }
423
424 mm_camera_super_buf_t *frame =
425 (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t));
426 if (frame == NULL) {
427 ALOGE("%s: No mem for mm_camera_buf_def_t", __func__);
428 stream->bufDone(recvd_frame->bufs[0]->buf_idx);
429 return;
430 }
431 *frame = *recvd_frame;
432 stream->processDataNotify(frame);
433 return;
434 }
435
436 /*===========================================================================
437 * FUNCTION : dataProcRoutine
438 *
439 * DESCRIPTION: function to process data in the main stream thread
440 *
441 * PARAMETERS :
442 * @data : user data ptr
443 *
444 * RETURN : none
445 *==========================================================================*/
dataProcRoutine(void * data)446 void *QCamera3Stream::dataProcRoutine(void *data)
447 {
448 int running = 1;
449 int ret;
450 QCamera3Stream *pme = (QCamera3Stream *)data;
451 QCameraCmdThread *cmdThread = &pme->mProcTh;
452 cmdThread->setName("cam_stream_proc");
453
454 ALOGV("%s: E", __func__);
455 do {
456 do {
457 ret = cam_sem_wait(&cmdThread->cmd_sem);
458 if (ret != 0 && errno != EINVAL) {
459 ALOGE("%s: cam_sem_wait error (%s)",
460 __func__, strerror(errno));
461 return NULL;
462 }
463 } while (ret != 0);
464
465 // we got notified about new cmd avail in cmd queue
466 camera_cmd_type_t cmd = cmdThread->getCmd();
467 switch (cmd) {
468 case CAMERA_CMD_TYPE_DO_NEXT_JOB:
469 {
470 ALOGV("%s: Do next job", __func__);
471 mm_camera_super_buf_t *frame =
472 (mm_camera_super_buf_t *)pme->mDataQ.dequeue();
473 if (NULL != frame) {
474 if (pme->mDataCB != NULL) {
475 pme->mDataCB(frame, pme, pme->mUserData);
476 } else {
477 // no data cb routine, return buf here
478 pme->bufDone(frame->bufs[0]->buf_idx);
479 }
480 }
481 }
482 break;
483 case CAMERA_CMD_TYPE_EXIT:
484 ALOGD("%s: Exit", __func__);
485 /* flush data buf queue */
486 pme->mDataQ.flush();
487 running = 0;
488 break;
489 default:
490 break;
491 }
492 } while (running);
493 ALOGV("%s: X", __func__);
494 return NULL;
495 }
496
497 /*===========================================================================
498 * FUNCTION : getInternalFormatBuffer
499 *
500 * DESCRIPTION: return buffer in the internal format structure
501 *
502 * PARAMETERS :
503 * @index : index of buffer to be returned
504 *
505 * RETURN : int32_t type of status
506 * NO_ERROR -- success
507 * none-zero failure code
508 *==========================================================================*/
getInternalFormatBuffer(int index)509 mm_camera_buf_def_t* QCamera3Stream::getInternalFormatBuffer(int index)
510 {
511 mm_camera_buf_def_t *rc = NULL;
512 if ((index >= mNumBufs) || (mBufDefs == NULL) ||
513 (NULL == mBufDefs[index].mem_info)) {
514 ALOGE("%s:Index out of range/no internal buffers yet", __func__);
515 return NULL;
516 }
517
518 rc = (mm_camera_buf_def_t*)malloc(sizeof(mm_camera_buf_def_t));
519 if(rc) {
520 memcpy(rc, &mBufDefs[index], sizeof(mm_camera_buf_def_t));
521 } else {
522 ALOGE("%s: Failed to allocate memory",__func__);
523 }
524 return rc;
525 }
526
527 /*===========================================================================
528 * FUNCTION : bufDone
529 *
530 * DESCRIPTION: return stream buffer to kernel
531 *
532 * PARAMETERS :
533 * @index : index of buffer to be returned
534 *
535 * RETURN : int32_t type of status
536 * NO_ERROR -- success
537 * none-zero failure code
538 *==========================================================================*/
bufDone(int index)539 int32_t QCamera3Stream::bufDone(int index)
540 {
541 int32_t rc = NO_ERROR;
542
543 if (index >= mNumBufs || mBufDefs == NULL)
544 return BAD_INDEX;
545
546 if( NULL == mBufDefs[index].mem_info) {
547 if (NULL == mMemOps) {
548 ALOGE("%s: Camera operations not initialized", __func__);
549 return NO_INIT;
550 }
551
552 rc = mMemOps->map_ops(index, -1, mStreamBufs->getFd(index),
553 mStreamBufs->getSize(index), mMemOps->userdata);
554 if (rc < 0) {
555 ALOGE("%s: Failed to map camera buffer %d", __func__, index);
556 return rc;
557 }
558
559 rc = mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[index], index);
560 if (NO_ERROR != rc) {
561 ALOGE("%s: Couldn't find camera buffer definition", __func__);
562 mMemOps->unmap_ops(index, -1, mMemOps->userdata);
563 return rc;
564 }
565 }
566
567 rc = mCamOps->qbuf(mCamHandle, mChannelHandle, &mBufDefs[index]);
568 if (rc < 0)
569 return FAILED_TRANSACTION;
570
571 return rc;
572 }
573
574 /*===========================================================================
575 * FUNCTION : getBufs
576 *
577 * DESCRIPTION: allocate stream buffers
578 *
579 * PARAMETERS :
580 * @offset : offset info of stream buffers
581 * @num_bufs : number of buffers allocated
582 * @initial_reg_flag: flag to indicate if buffer needs to be registered
583 * at kernel initially
584 * @bufs : output of allocated buffers
585 * @ops_tbl : ptr to buf mapping/unmapping ops
586 *
587 * RETURN : int32_t type of status
588 * NO_ERROR -- success
589 * none-zero failure code
590 *==========================================================================*/
getBufs(cam_frame_len_offset_t * offset,uint8_t * num_bufs,uint8_t ** initial_reg_flag,mm_camera_buf_def_t ** bufs,mm_camera_map_unmap_ops_tbl_t * ops_tbl)591 int32_t QCamera3Stream::getBufs(cam_frame_len_offset_t *offset,
592 uint8_t *num_bufs,
593 uint8_t **initial_reg_flag,
594 mm_camera_buf_def_t **bufs,
595 mm_camera_map_unmap_ops_tbl_t *ops_tbl)
596 {
597 int rc = NO_ERROR;
598 uint8_t *regFlags;
599
600 if (!ops_tbl) {
601 ALOGE("%s: ops_tbl is NULL", __func__);
602 return INVALID_OPERATION;
603 }
604
605 mFrameLenOffset = *offset;
606 mMemOps = ops_tbl;
607
608 mStreamBufs = mChannel->getStreamBufs(mFrameLenOffset.frame_len);
609 if (!mStreamBufs) {
610 ALOGE("%s: Failed to allocate stream buffers", __func__);
611 return NO_MEMORY;
612 }
613
614 int registeredBuffers = mStreamBufs->getCnt();
615 for (int i = 0; i < registeredBuffers; i++) {
616 rc = ops_tbl->map_ops(i, -1, mStreamBufs->getFd(i),
617 mStreamBufs->getSize(i), ops_tbl->userdata);
618 if (rc < 0) {
619 ALOGE("%s: map_stream_buf failed: %d", __func__, rc);
620 for (int j = 0; j < i; j++) {
621 ops_tbl->unmap_ops(j, -1, ops_tbl->userdata);
622 }
623 return INVALID_OPERATION;
624 }
625 }
626
627 //regFlags array is allocated by us, but consumed and freed by mm-camera-interface
628 regFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs);
629 if (!regFlags) {
630 ALOGE("%s: Out of memory", __func__);
631 for (int i = 0; i < registeredBuffers; i++) {
632 ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
633 }
634 return NO_MEMORY;
635 }
636 memset(regFlags, 0, sizeof(uint8_t) * mNumBufs);
637
638 mBufDefs = (mm_camera_buf_def_t *)malloc(mNumBufs * sizeof(mm_camera_buf_def_t));
639 if (mBufDefs == NULL) {
640 ALOGE("%s: Failed to allocate mm_camera_buf_def_t %d", __func__, rc);
641 for (int i = 0; i < registeredBuffers; i++) {
642 ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
643 }
644 free(regFlags);
645 regFlags = NULL;
646 return INVALID_OPERATION;
647 }
648 memset(mBufDefs, 0, mNumBufs * sizeof(mm_camera_buf_def_t));
649 for (int i = 0; i < registeredBuffers; i++) {
650 mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[i], i);
651 }
652
653 rc = mStreamBufs->getRegFlags(regFlags);
654 if (rc < 0) {
655 ALOGE("%s: getRegFlags failed %d", __func__, rc);
656 for (int i = 0; i < registeredBuffers; i++) {
657 ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
658 }
659 free(mBufDefs);
660 mBufDefs = NULL;
661 free(regFlags);
662 regFlags = NULL;
663 return INVALID_OPERATION;
664 }
665
666 *num_bufs = mNumBufs;
667 *initial_reg_flag = regFlags;
668 *bufs = mBufDefs;
669 return NO_ERROR;
670 }
671
672 /*===========================================================================
673 * FUNCTION : putBufs
674 *
675 * DESCRIPTION: deallocate stream buffers
676 *
677 * PARAMETERS :
678 * @ops_tbl : ptr to buf mapping/unmapping ops
679 *
680 * RETURN : int32_t type of status
681 * NO_ERROR -- success
682 * none-zero failure code
683 *==========================================================================*/
putBufs(mm_camera_map_unmap_ops_tbl_t * ops_tbl)684 int32_t QCamera3Stream::putBufs(mm_camera_map_unmap_ops_tbl_t *ops_tbl)
685 {
686 int rc = NO_ERROR;
687 for (int i = 0; i < mNumBufs; i++) {
688 if (NULL != mBufDefs[i].mem_info) {
689 rc = ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
690 if (rc < 0) {
691 ALOGE("%s: map_stream_buf failed: %d", __func__, rc);
692 }
693 }
694 }
695 mBufDefs = NULL; // mBufDefs just keep a ptr to the buffer
696 // mm-camera-interface own the buffer, so no need to free
697 memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
698 mChannel->putStreamBufs();
699
700 return rc;
701 }
702
703 /*===========================================================================
704 * FUNCTION : invalidateBuf
705 *
706 * DESCRIPTION: invalidate a specific stream buffer
707 *
708 * PARAMETERS :
709 * @index : index of the buffer to invalidate
710 *
711 * RETURN : int32_t type of status
712 * NO_ERROR -- success
713 * none-zero failure code
714 *==========================================================================*/
invalidateBuf(int index)715 int32_t QCamera3Stream::invalidateBuf(int index)
716 {
717 return mStreamBufs->invalidateCache(index);
718 }
719
720 /*===========================================================================
721 * FUNCTION : cleanInvalidateBuf
722 *
723 * DESCRIPTION: clean and invalidate a specific stream buffer
724 *
725 * PARAMETERS :
726 * @index : index of the buffer to invalidate
727 *
728 * RETURN : int32_t type of status
729 * NO_ERROR -- success
730 * none-zero failure code
731 *==========================================================================*/
cleanInvalidateBuf(int index)732 int32_t QCamera3Stream::cleanInvalidateBuf(int index)
733 {
734 return mStreamBufs->cleanInvalidateCache(index);
735 }
736
737 /*===========================================================================
738 * FUNCTION : getFrameOffset
739 *
740 * DESCRIPTION: query stream buffer frame offset info
741 *
742 * PARAMETERS :
743 * @offset : reference to struct to store the queried frame offset info
744 *
745 * RETURN : int32_t type of status
746 * NO_ERROR -- success
747 * none-zero failure code
748 *==========================================================================*/
getFrameOffset(cam_frame_len_offset_t & offset)749 int32_t QCamera3Stream::getFrameOffset(cam_frame_len_offset_t &offset)
750 {
751 offset = mFrameLenOffset;
752 return 0;
753 }
754
755 /*===========================================================================
756 * FUNCTION : getFrameDimension
757 *
758 * DESCRIPTION: query stream frame dimension info
759 *
760 * PARAMETERS :
761 * @dim : reference to struct to store the queried frame dimension
762 *
763 * RETURN : int32_t type of status
764 * NO_ERROR -- success
765 * none-zero failure code
766 *==========================================================================*/
getFrameDimension(cam_dimension_t & dim)767 int32_t QCamera3Stream::getFrameDimension(cam_dimension_t &dim)
768 {
769 if (mStreamInfo != NULL) {
770 dim = mStreamInfo->dim;
771 return 0;
772 }
773 return -1;
774 }
775
776 /*===========================================================================
777 * FUNCTION : getFormat
778 *
779 * DESCRIPTION: query stream format
780 *
781 * PARAMETERS :
782 * @fmt : reference to stream format
783 *
784 * RETURN : int32_t type of status
785 * NO_ERROR -- success
786 * none-zero failure code
787 *==========================================================================*/
getFormat(cam_format_t & fmt)788 int32_t QCamera3Stream::getFormat(cam_format_t &fmt)
789 {
790 if (mStreamInfo != NULL) {
791 fmt = mStreamInfo->fmt;
792 return 0;
793 }
794 return -1;
795 }
796
797 /*===========================================================================
798 * FUNCTION : getMyServerID
799 *
800 * DESCRIPTION: query server stream ID
801 *
802 * PARAMETERS : None
803 *
804 * RETURN : stream ID from server
805 *==========================================================================*/
getMyServerID()806 uint32_t QCamera3Stream::getMyServerID() {
807 if (mStreamInfo != NULL) {
808 return mStreamInfo->stream_svr_id;
809 } else {
810 return 0;
811 }
812 }
813
814 /*===========================================================================
815 * FUNCTION : getMyType
816 *
817 * DESCRIPTION: query stream type
818 *
819 * PARAMETERS : None
820 *
821 * RETURN : type of stream
822 *==========================================================================*/
getMyType() const823 cam_stream_type_t QCamera3Stream::getMyType() const
824 {
825 if (mStreamInfo != NULL) {
826 return mStreamInfo->stream_type;
827 } else {
828 return CAM_STREAM_TYPE_MAX;
829 }
830 }
831
832 /*===========================================================================
833 * FUNCTION : mapBuf
834 *
835 * DESCRIPTION: map stream related buffer to backend server
836 *
837 * PARAMETERS :
838 * @buf_type : mapping type of buffer
839 * @buf_idx : index of buffer
840 * @plane_idx: plane index
841 * @fd : fd of the buffer
842 * @size : lenght of the buffer
843 *
844 * RETURN : int32_t type of status
845 * NO_ERROR -- success
846 * none-zero failure code
847 *==========================================================================*/
mapBuf(uint8_t buf_type,uint32_t buf_idx,int32_t plane_idx,int fd,uint32_t size)848 int32_t QCamera3Stream::mapBuf(uint8_t buf_type,
849 uint32_t buf_idx,
850 int32_t plane_idx,
851 int fd,
852 uint32_t size)
853 {
854 return mCamOps->map_stream_buf(mCamHandle, mChannelHandle,
855 mHandle, buf_type,
856 buf_idx, plane_idx,
857 fd, size);
858
859 }
860
861 /*===========================================================================
862 * FUNCTION : unmapBuf
863 *
864 * DESCRIPTION: unmap stream related buffer to backend server
865 *
866 * PARAMETERS :
867 * @buf_type : mapping type of buffer
868 * @buf_idx : index of buffer
869 * @plane_idx: plane index
870 *
871 * RETURN : int32_t type of status
872 * NO_ERROR -- success
873 * none-zero failure code
874 *==========================================================================*/
unmapBuf(uint8_t buf_type,uint32_t buf_idx,int32_t plane_idx)875 int32_t QCamera3Stream::unmapBuf(uint8_t buf_type, uint32_t buf_idx, int32_t plane_idx)
876 {
877 return mCamOps->unmap_stream_buf(mCamHandle, mChannelHandle,
878 mHandle, buf_type,
879 buf_idx, plane_idx);
880 }
881
882 /*===========================================================================
883 * FUNCTION : setParameter
884 *
885 * DESCRIPTION: set stream based parameters
886 *
887 * PARAMETERS :
888 * @param : ptr to parameters to be set
889 *
890 * RETURN : int32_t type of status
891 * NO_ERROR -- success
892 * none-zero failure code
893 *==========================================================================*/
setParameter(cam_stream_parm_buffer_t & param)894 int32_t QCamera3Stream::setParameter(cam_stream_parm_buffer_t ¶m)
895 {
896 int32_t rc = NO_ERROR;
897 mStreamInfo->parm_buf = param;
898 rc = mCamOps->set_stream_parms(mCamHandle,
899 mChannelHandle,
900 mHandle,
901 &mStreamInfo->parm_buf);
902 if (rc == NO_ERROR) {
903 param = mStreamInfo->parm_buf;
904 }
905 return rc;
906 }
907
908 /*===========================================================================
909 * FUNCTION : releaseFrameData
910 *
911 * DESCRIPTION: callback function to release frame data node
912 *
913 * PARAMETERS :
914 * @data : ptr to post process input data
915 * @user_data : user data ptr (QCameraReprocessor)
916 *
917 * RETURN : None
918 *==========================================================================*/
releaseFrameData(void * data,void * user_data)919 void QCamera3Stream::releaseFrameData(void *data, void *user_data)
920 {
921 QCamera3Stream *pme = (QCamera3Stream *)user_data;
922 mm_camera_super_buf_t *frame = (mm_camera_super_buf_t *)data;
923 if (NULL != pme) {
924 pme->bufDone(frame->bufs[0]->buf_idx);
925 }
926 }
927
928 }; // namespace qcamera
929