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