1/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 *     * Redistributions of source code must retain the above copyright
7 *       notice, this list of conditions and the following disclaimer.
8 *     * Redistributions in binary form must reproduce the above
9 *       copyright notice, this list of conditions and the following
10 *       disclaimer in the documentation and/or other materials provided
11 *       with the distribution.
12 *     * Neither the name of The Linux Foundation nor the names of its
13 *       contributors may be used to endorse or promote products derived
14 *       from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29#define LOG_TAG "QCameraHWI_Mem"
30
31// System dependencies
32#include <fcntl.h>
33#include <stdio.h>
34#include <utils/Errors.h>
35#define MMAN_H <SYSTEM_HEADER_PREFIX/mman.h>
36#include MMAN_H
37#include "gralloc.h"
38#include "gralloc_priv.h"
39
40// OpenMAX dependencies
41#include "OMX_QCOMExtns.h"
42#include "QComOMXMetadata.h"
43
44// Camera dependencies
45#include "QCamera2HWI.h"
46#include "QCameraMem.h"
47#include "QCameraParameters.h"
48#include "QCameraTrace.h"
49
50extern "C" {
51#include "mm_camera_dbg.h"
52#include "mm_camera_interface.h"
53}
54
55using namespace android;
56
57namespace qcamera {
58
59// QCaemra2Memory base class
60
61/*===========================================================================
62 * FUNCTION   : QCameraMemory
63 *
64 * DESCRIPTION: default constructor of QCameraMemory
65 *
66 * PARAMETERS :
67 *   @cached  : flag indicates if using cached memory
68 *
69 * RETURN     : None
70 *==========================================================================*/
71QCameraMemory::QCameraMemory(bool cached,
72        QCameraMemoryPool *pool,
73        cam_stream_type_t streamType, QCameraMemType bufType)
74    :m_bCached(cached),
75     mMemoryPool(pool),
76     mStreamType(streamType),
77     mBufType(bufType)
78{
79    mBufferCount = 0;
80    reset();
81}
82
83/*===========================================================================
84 * FUNCTION   : ~QCameraMemory
85 *
86 * DESCRIPTION: deconstructor of QCameraMemory
87 *
88 * PARAMETERS : none
89 *
90 * RETURN     : None
91 *==========================================================================*/
92QCameraMemory::~QCameraMemory()
93{
94}
95
96/*===========================================================================
97 * FUNCTION   : cacheOpsInternal
98 *
99 * DESCRIPTION: ion related memory cache operations
100 *
101 * PARAMETERS :
102 *   @index   : index of the buffer
103 *   @cmd     : cache ops command
104 *   @vaddr   : ptr to the virtual address
105 *
106 * RETURN     : int32_t type of status
107 *              NO_ERROR  -- success
108 *              none-zero failure code
109 *==========================================================================*/
110int QCameraMemory::cacheOpsInternal(uint32_t index, unsigned int cmd, void *vaddr)
111{
112    if (!m_bCached) {
113        // Memory is not cached, no need for cache ops
114        LOGD("No cache ops here for uncached memory");
115        return OK;
116    }
117
118    struct ion_flush_data cache_inv_data;
119    struct ion_custom_data custom_data;
120    int ret = OK;
121
122    if (index >= mBufferCount) {
123        LOGE("index %d out of bound [0, %d)", index, mBufferCount);
124        return BAD_INDEX;
125    }
126
127    memset(&cache_inv_data, 0, sizeof(cache_inv_data));
128    memset(&custom_data, 0, sizeof(custom_data));
129    cache_inv_data.vaddr = vaddr;
130    cache_inv_data.fd = mMemInfo[index].fd;
131    cache_inv_data.handle = mMemInfo[index].handle;
132    cache_inv_data.length =
133            ( /* FIXME: Should remove this after ION interface changes */ unsigned int)
134            mMemInfo[index].size;
135    custom_data.cmd = cmd;
136    custom_data.arg = (unsigned long)&cache_inv_data;
137
138    LOGH("addr = %p, fd = %d, handle = %lx length = %d, ION Fd = %d",
139          cache_inv_data.vaddr, cache_inv_data.fd,
140         (unsigned long)cache_inv_data.handle, cache_inv_data.length,
141         mMemInfo[index].main_ion_fd);
142    ret = ioctl(mMemInfo[index].main_ion_fd, ION_IOC_CUSTOM, &custom_data);
143    if (ret < 0) {
144        LOGE("Cache Invalidate failed: %s\n", strerror(errno));
145    }
146
147    return ret;
148}
149
150/*===========================================================================
151 * FUNCTION   : getFd
152 *
153 * DESCRIPTION: return file descriptor of the indexed buffer
154 *
155 * PARAMETERS :
156 *   @index   : index of the buffer
157 *
158 * RETURN     : file descriptor
159 *==========================================================================*/
160int QCameraMemory::getFd(uint32_t index) const
161{
162    if (index >= mBufferCount)
163        return BAD_INDEX;
164
165    return mMemInfo[index].fd;
166}
167
168/*===========================================================================
169 * FUNCTION   : getSize
170 *
171 * DESCRIPTION: return buffer size of the indexed buffer
172 *
173 * PARAMETERS :
174 *   @index   : index of the buffer
175 *
176 * RETURN     : buffer size
177 *==========================================================================*/
178ssize_t QCameraMemory::getSize(uint32_t index) const
179{
180    if (index >= mBufferCount)
181        return BAD_INDEX;
182
183    return (ssize_t)mMemInfo[index].size;
184}
185
186/*===========================================================================
187 * FUNCTION   : getCnt
188 *
189 * DESCRIPTION: query number of buffers allocated
190 *
191 * PARAMETERS : none
192 *
193 * RETURN     : number of buffers allocated
194 *==========================================================================*/
195uint8_t QCameraMemory::getCnt() const
196{
197    return mBufferCount;
198}
199
200/*===========================================================================
201 * FUNCTION   : reset
202 *
203 * DESCRIPTION: reset member variables
204 *
205 * PARAMETERS : none
206 *
207 * RETURN     : none
208 *==========================================================================*/
209void QCameraMemory::reset()
210{
211    size_t i, count;
212
213    memset(mMemInfo, 0, sizeof(mMemInfo));
214
215    count = sizeof(mMemInfo) / sizeof(mMemInfo[0]);
216    for (i = 0; i < count; i++) {
217        mMemInfo[i].fd = -1;
218        mMemInfo[i].main_ion_fd = -1;
219    }
220
221    return;
222}
223
224/*===========================================================================
225 * FUNCTION   : getMappable
226 *
227 * DESCRIPTION: query number of buffers available to map
228 *
229 * PARAMETERS : none
230 *
231 * RETURN     : number of buffers available to map
232 *==========================================================================*/
233uint8_t QCameraMemory::getMappable() const
234{
235    return mBufferCount;
236}
237
238/*===========================================================================
239 * FUNCTION   : checkIfAllBuffersMapped
240 *
241 * DESCRIPTION: query if all buffers are mapped
242 *
243 * PARAMETERS : none
244 *
245 * RETURN     : 1 as buffer count is always equal to mappable count
246 *==========================================================================*/
247uint8_t QCameraMemory::checkIfAllBuffersMapped() const
248{
249    return 1;
250}
251
252
253/*===========================================================================
254 * FUNCTION   : getBufDef
255 *
256 * DESCRIPTION: query detailed buffer information
257 *
258 * PARAMETERS :
259 *   @offset  : [input] frame buffer offset
260 *   @bufDef  : [output] reference to struct to store buffer definition
261 *   @index   : [input] index of the buffer
262 *
263 * RETURN     : none
264 *==========================================================================*/
265void QCameraMemory::getBufDef(const cam_frame_len_offset_t &offset,
266        mm_camera_buf_def_t &bufDef, uint32_t index) const
267{
268    if (!mBufferCount) {
269        LOGE("Memory not allocated");
270        return;
271    }
272    bufDef.fd = mMemInfo[index].fd;
273    bufDef.frame_len = mMemInfo[index].size;
274    bufDef.buf_type = CAM_STREAM_BUF_TYPE_MPLANE;
275    bufDef.mem_info = (void *)this;
276    bufDef.planes_buf.num_planes = (int8_t)offset.num_planes;
277    bufDef.buffer = getPtr(index);
278    bufDef.buf_idx = index;
279
280    /* Plane 0 needs to be set separately. Set other planes in a loop */
281    bufDef.planes_buf.planes[0].length = offset.mp[0].len;
282    bufDef.planes_buf.planes[0].m.userptr = (long unsigned int)mMemInfo[index].fd;
283    bufDef.planes_buf.planes[0].data_offset = offset.mp[0].offset;
284    bufDef.planes_buf.planes[0].reserved[0] = 0;
285    for (int i = 1; i < bufDef.planes_buf.num_planes; i++) {
286         bufDef.planes_buf.planes[i].length = offset.mp[i].len;
287         bufDef.planes_buf.planes[i].m.userptr = (long unsigned int)mMemInfo[i].fd;
288         bufDef.planes_buf.planes[i].data_offset = offset.mp[i].offset;
289         bufDef.planes_buf.planes[i].reserved[0] =
290                 bufDef.planes_buf.planes[i-1].reserved[0] +
291                 bufDef.planes_buf.planes[i-1].length;
292    }
293}
294
295/*===========================================================================
296 * FUNCTION   : getUserBufDef
297 *
298 * DESCRIPTION: Fill Buffer structure with user buffer information
299                           This also fills individual stream buffers inside batch baffer strcuture
300 *
301 * PARAMETERS :
302 *   @buf_info : user buffer information
303 *   @bufDef  : Buffer strcuture to fill user buf info
304 *   @index   : index of the buffer
305 *   @plane_offset : plane buffer information
306 *   @planeBufDef  : [input] frame buffer offset
307 *   @bufs    : Stream Buffer object
308 *
309 * RETURN     : int32_t type of status
310 *              NO_ERROR  -- success
311 *              none-zero failure code
312 *==========================================================================*/
313int32_t QCameraMemory::getUserBufDef(const cam_stream_user_buf_info_t &buf_info,
314        mm_camera_buf_def_t &bufDef,
315        uint32_t index,
316        const cam_frame_len_offset_t &plane_offset,
317        mm_camera_buf_def_t *planeBufDef,
318        QCameraMemory *bufs) const
319{
320    struct msm_camera_user_buf_cont_t *cont_buf = NULL;
321    uint32_t plane_idx = (index * buf_info.frame_buf_cnt);
322
323    if (!mBufferCount) {
324        LOGE("Memory not allocated");
325        return INVALID_OPERATION;
326    }
327
328    for (int count = 0; count < mBufferCount; count++) {
329        bufDef.fd = mMemInfo[count].fd;
330        bufDef.buf_type = CAM_STREAM_BUF_TYPE_USERPTR;
331        bufDef.frame_len = buf_info.size;
332        bufDef.mem_info = (void *)this;
333        bufDef.buffer = (void *)((uint8_t *)getPtr(count)
334                + (index * buf_info.size));
335        bufDef.buf_idx = index;
336        bufDef.user_buf.num_buffers = (int8_t)buf_info.frame_buf_cnt;
337        bufDef.user_buf.bufs_used = (int8_t)buf_info.frame_buf_cnt;
338
339        //Individual plane buffer structure to be filled
340        cont_buf = (struct msm_camera_user_buf_cont_t *)bufDef.buffer;
341        cont_buf->buf_cnt = bufDef.user_buf.num_buffers;
342
343        for (int i = 0; i < bufDef.user_buf.num_buffers; i++) {
344            bufs->getBufDef(plane_offset, planeBufDef[plane_idx], plane_idx);
345            bufDef.user_buf.buf_idx[i] = -1;
346            cont_buf->buf_idx[i] = planeBufDef[plane_idx].buf_idx;
347            plane_idx++;
348        }
349        bufDef.user_buf.plane_buf = planeBufDef;
350
351        LOGD("num_buf = %d index = %d plane_idx = %d",
352                 bufDef.user_buf.num_buffers, index, plane_idx);
353    }
354    return NO_ERROR;
355}
356
357
358/*===========================================================================
359 * FUNCTION   : alloc
360 *
361 * DESCRIPTION: allocate requested number of buffers of certain size
362 *
363 * PARAMETERS :
364 *   @count   : number of buffers to be allocated
365 *   @size    : lenght of the buffer to be allocated
366 *   @heap_id : heap id to indicate where the buffers will be allocated from
367 *
368 * RETURN     : int32_t type of status
369 *              NO_ERROR  -- success
370 *              none-zero failure code
371 *==========================================================================*/
372int QCameraMemory::alloc(int count, size_t size, unsigned int heap_id,
373        uint32_t secure_mode)
374{
375    int rc = OK;
376
377    int new_bufCnt = mBufferCount + count;
378    ATRACE_BEGIN_SNPRINTF("%s %zu %d", "Memsize", size, count);
379
380    if (new_bufCnt > MM_CAMERA_MAX_NUM_FRAMES) {
381        LOGE("Buffer count %d out of bound. Max is %d",
382               new_bufCnt, MM_CAMERA_MAX_NUM_FRAMES);
383        ATRACE_END();
384        return BAD_INDEX;
385    }
386
387    for (int i = mBufferCount; i < new_bufCnt; i ++) {
388        if ( NULL == mMemoryPool ) {
389            LOGH("No memory pool available, allocating now");
390            rc = allocOneBuffer(mMemInfo[i], heap_id, size, m_bCached,
391                     secure_mode);
392            if (rc < 0) {
393                LOGE("AllocateIonMemory failed");
394                for (int j = i-1; j >= 0; j--)
395                    deallocOneBuffer(mMemInfo[j]);
396                break;
397            }
398        } else {
399            rc = mMemoryPool->allocateBuffer(mMemInfo[i],
400                                             heap_id,
401                                             size,
402                                             m_bCached,
403                                             mStreamType,
404                                             secure_mode);
405            if (rc < 0) {
406                LOGE("Memory pool allocation failed");
407                for (int j = i-1; j >= 0; j--)
408                    mMemoryPool->releaseBuffer(mMemInfo[j],
409                                               mStreamType);
410                break;
411            }
412        }
413
414    }
415    ATRACE_END();
416    return rc;
417}
418
419/*===========================================================================
420 * FUNCTION   : dealloc
421 *
422 * DESCRIPTION: deallocate buffers
423 *
424 * PARAMETERS : none
425 *
426 * RETURN     : none
427 *==========================================================================*/
428void QCameraMemory::dealloc()
429{
430    for (int i = 0; i < mBufferCount; i++) {
431        if ( NULL == mMemoryPool ) {
432            deallocOneBuffer(mMemInfo[i]);
433        } else {
434            mMemoryPool->releaseBuffer(mMemInfo[i], mStreamType);
435        }
436    }
437}
438
439/*===========================================================================
440 * FUNCTION   : allocOneBuffer
441 *
442 * DESCRIPTION: impl of allocating one buffers of certain size
443 *
444 * PARAMETERS :
445 *   @memInfo : [output] reference to struct to store additional memory allocation info
446 *   @heap    : [input] heap id to indicate where the buffers will be allocated from
447 *   @size    : [input] lenght of the buffer to be allocated
448 *   @cached  : [input] flag whether buffer needs to be cached
449 *
450 * RETURN     : int32_t type of status
451 *              NO_ERROR  -- success
452 *              none-zero failure code
453 *==========================================================================*/
454int QCameraMemory::allocOneBuffer(QCameraMemInfo &memInfo,
455        unsigned int heap_id, size_t size, bool cached, uint32_t secure_mode)
456{
457    int rc = OK;
458    struct ion_handle_data handle_data;
459    struct ion_allocation_data alloc;
460    struct ion_fd_data ion_info_fd;
461    int main_ion_fd = -1;
462
463    main_ion_fd = open("/dev/ion", O_RDONLY);
464    if (main_ion_fd < 0) {
465        LOGE("Ion dev open failed: %s\n", strerror(errno));
466        goto ION_OPEN_FAILED;
467    }
468
469    memset(&alloc, 0, sizeof(alloc));
470    alloc.len = size;
471    /* to make it page size aligned */
472    alloc.len = (alloc.len + 4095U) & (~4095U);
473    alloc.align = 4096;
474    if (cached) {
475        alloc.flags = ION_FLAG_CACHED;
476    }
477    alloc.heap_id_mask = heap_id;
478    if (secure_mode == SECURE) {
479        LOGD("Allocate secure buffer\n");
480        alloc.flags = ION_SECURE;
481        alloc.heap_id_mask = ION_HEAP(ION_CP_MM_HEAP_ID);
482        alloc.align = 1048576; // 1 MiB alignment to be able to protect later
483        alloc.len = (alloc.len + 1048575U) & (~1048575U);
484    }
485
486    rc = ioctl(main_ion_fd, ION_IOC_ALLOC, &alloc);
487    if (rc < 0) {
488        LOGE("ION allocation failed: %s\n", strerror(errno));
489        goto ION_ALLOC_FAILED;
490    }
491
492    memset(&ion_info_fd, 0, sizeof(ion_info_fd));
493    ion_info_fd.handle = alloc.handle;
494    rc = ioctl(main_ion_fd, ION_IOC_SHARE, &ion_info_fd);
495    if (rc < 0) {
496        LOGE("ION map failed %s\n", strerror(errno));
497        goto ION_MAP_FAILED;
498    }
499
500    memInfo.main_ion_fd = main_ion_fd;
501    memInfo.fd = ion_info_fd.fd;
502    memInfo.handle = ion_info_fd.handle;
503    memInfo.size = alloc.len;
504    memInfo.cached = cached;
505    memInfo.heap_id = heap_id;
506
507    LOGD("ION buffer %lx with size %d allocated",
508             (unsigned long)memInfo.handle, alloc.len);
509    return OK;
510
511ION_MAP_FAILED:
512    memset(&handle_data, 0, sizeof(handle_data));
513    handle_data.handle = ion_info_fd.handle;
514    ioctl(main_ion_fd, ION_IOC_FREE, &handle_data);
515ION_ALLOC_FAILED:
516    close(main_ion_fd);
517ION_OPEN_FAILED:
518    return NO_MEMORY;
519}
520
521/*===========================================================================
522 * FUNCTION   : deallocOneBuffer
523 *
524 * DESCRIPTION: impl of deallocating one buffers
525 *
526 * PARAMETERS :
527 *   @memInfo : reference to struct that stores additional memory allocation info
528 *
529 * RETURN     : none
530 *==========================================================================*/
531void QCameraMemory::deallocOneBuffer(QCameraMemInfo &memInfo)
532{
533    struct ion_handle_data handle_data;
534
535    if (memInfo.fd >= 0) {
536        close(memInfo.fd);
537        memInfo.fd = -1;
538    }
539
540    if (memInfo.main_ion_fd >= 0) {
541        memset(&handle_data, 0, sizeof(handle_data));
542        handle_data.handle = memInfo.handle;
543        ioctl(memInfo.main_ion_fd, ION_IOC_FREE, &handle_data);
544        close(memInfo.main_ion_fd);
545        memInfo.main_ion_fd = -1;
546    }
547    memInfo.handle = 0;
548    memInfo.size = 0;
549}
550
551/*===========================================================================
552 * FUNCTION   : QCameraMemoryPool
553 *
554 * DESCRIPTION: default constructor of QCameraMemoryPool
555 *
556 * PARAMETERS : None
557 *
558 * RETURN     : None
559 *==========================================================================*/
560QCameraMemoryPool::QCameraMemoryPool()
561{
562    pthread_mutex_init(&mLock, NULL);
563}
564
565
566/*===========================================================================
567 * FUNCTION   : ~QCameraMemoryPool
568 *
569 * DESCRIPTION: deconstructor of QCameraMemoryPool
570 *
571 * PARAMETERS : None
572 *
573 * RETURN     : None
574 *==========================================================================*/
575QCameraMemoryPool::~QCameraMemoryPool()
576{
577    clear();
578    pthread_mutex_destroy(&mLock);
579}
580
581/*===========================================================================
582 * FUNCTION   : releaseBuffer
583 *
584 * DESCRIPTION: release one cached buffers
585 *
586 * PARAMETERS :
587 *   @memInfo : reference to struct that stores additional memory allocation info
588 *   @streamType: Type of stream the buffers belongs to
589 *
590 * RETURN     : none
591 *==========================================================================*/
592void QCameraMemoryPool::releaseBuffer(
593        struct QCameraMemory::QCameraMemInfo &memInfo,
594        cam_stream_type_t streamType)
595{
596    pthread_mutex_lock(&mLock);
597
598    mPools[streamType].push_back(memInfo);
599
600    pthread_mutex_unlock(&mLock);
601}
602
603/*===========================================================================
604 * FUNCTION   : clear
605 *
606 * DESCRIPTION: clears all cached buffers
607 *
608 * PARAMETERS : none
609 *
610 * RETURN     : none
611 *==========================================================================*/
612void QCameraMemoryPool::clear()
613{
614    pthread_mutex_lock(&mLock);
615
616    for (int i = CAM_STREAM_TYPE_DEFAULT; i < CAM_STREAM_TYPE_MAX; i++ ) {
617        List<struct QCameraMemory::QCameraMemInfo>::iterator it;
618        it = mPools[i].begin();
619        for( ; it != mPools[i].end() ; it++) {
620            QCameraMemory::deallocOneBuffer(*it);
621        }
622
623        mPools[i].clear();
624    }
625
626    pthread_mutex_unlock(&mLock);
627}
628
629/*===========================================================================
630 * FUNCTION   : findBufferLocked
631 *
632 * DESCRIPTION: search for a appropriate cached buffer
633 *
634 * PARAMETERS :
635 *   @memInfo : reference to struct that stores additional memory allocation info
636 *   @heap_id : type of heap
637 *   @size    : size of the buffer
638 *   @cached  : whether the buffer should be cached
639 *   @streaType: type of stream this buffer belongs to
640 *
641 * RETURN     : int32_t type of status
642 *              NO_ERROR  -- success
643 *              none-zero failure code
644 *==========================================================================*/
645int QCameraMemoryPool::findBufferLocked(
646        struct QCameraMemory::QCameraMemInfo &memInfo, unsigned int heap_id,
647        size_t size, bool cached, cam_stream_type_t streamType)
648{
649    int rc = NAME_NOT_FOUND;
650
651    if (mPools[streamType].empty()) {
652        return NAME_NOT_FOUND;
653    }
654
655    List<struct QCameraMemory::QCameraMemInfo>::iterator it = mPools[streamType].begin();
656    if (streamType == CAM_STREAM_TYPE_OFFLINE_PROC) {
657        for( ; it != mPools[streamType].end() ; it++) {
658            if( ((*it).size == size) &&
659                    ((*it).heap_id == heap_id) &&
660                    ((*it).cached == cached) ) {
661                memInfo = *it;
662                LOGD("Found buffer %lx size %d",
663                         (unsigned long)memInfo.handle, memInfo.size);
664                mPools[streamType].erase(it);
665                rc = NO_ERROR;
666                break;
667            }
668        }
669    } else {
670        for( ; it != mPools[streamType].end() ; it++) {
671            if(((*it).size >= size) &&
672                    ((*it).heap_id == heap_id) &&
673                    ((*it).cached == cached) ) {
674                memInfo = *it;
675                LOGD("Found buffer %lx size %d",
676                         (unsigned long)memInfo.handle, memInfo.size);
677                mPools[streamType].erase(it);
678                rc = NO_ERROR;
679                break;
680            }
681        }
682    }
683
684    return rc;
685}
686
687/*===========================================================================
688 * FUNCTION   : allocateBuffer
689 *
690 * DESCRIPTION: allocates a buffer from the memory pool,
691 *              it will re-use cached buffers if possible
692 *
693 * PARAMETERS :
694 *   @memInfo : reference to struct that stores additional memory allocation info
695 *   @heap_id : type of heap
696 *   @size    : size of the buffer
697 *   @cached  : whether the buffer should be cached
698 *   @streaType: type of stream this buffer belongs to
699 *
700 * RETURN     : int32_t type of status
701 *              NO_ERROR  -- success
702 *              none-zero failure code
703 *==========================================================================*/
704int QCameraMemoryPool::allocateBuffer(
705        struct QCameraMemory::QCameraMemInfo &memInfo, unsigned int heap_id,
706        size_t size, bool cached, cam_stream_type_t streamType,
707        uint32_t secure_mode)
708{
709    int rc = NO_ERROR;
710
711    pthread_mutex_lock(&mLock);
712
713    rc = findBufferLocked(memInfo, heap_id, size, cached, streamType);
714    if (NAME_NOT_FOUND == rc ) {
715        LOGD("Buffer not found!");
716        rc = QCameraMemory::allocOneBuffer(memInfo, heap_id, size, cached,
717                 secure_mode);
718    }
719
720    pthread_mutex_unlock(&mLock);
721
722    return rc;
723}
724
725/*===========================================================================
726 * FUNCTION   : QCameraHeapMemory
727 *
728 * DESCRIPTION: constructor of QCameraHeapMemory for ion memory used internally in HAL
729 *
730 * PARAMETERS :
731 *   @cached  : flag indicates if using cached memory
732 *
733 * RETURN     : none
734 *==========================================================================*/
735QCameraHeapMemory::QCameraHeapMemory(bool cached)
736    : QCameraMemory(cached)
737{
738    for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i ++)
739        mPtr[i] = NULL;
740}
741
742/*===========================================================================
743 * FUNCTION   : ~QCameraHeapMemory
744 *
745 * DESCRIPTION: deconstructor of QCameraHeapMemory
746 *
747 * PARAMETERS : none
748 *
749 * RETURN     : none
750 *==========================================================================*/
751QCameraHeapMemory::~QCameraHeapMemory()
752{
753}
754
755/*===========================================================================
756 * FUNCTION   : getPtr
757 *
758 * DESCRIPTION: return buffer pointer
759 *
760 * PARAMETERS :
761 *   @index   : index of the buffer
762 *
763 * RETURN     : buffer ptr
764 *==========================================================================*/
765void *QCameraHeapMemory::getPtr(uint32_t index) const
766{
767    if (index >= mBufferCount) {
768        LOGE("index out of bound");
769        return (void *)BAD_INDEX;
770    }
771    return mPtr[index];
772}
773
774/*===========================================================================
775 * FUNCTION   : allocate
776 *
777 * DESCRIPTION: allocate requested number of buffers of certain size
778 *
779 * PARAMETERS :
780 *   @count   : number of buffers to be allocated
781 *   @size    : lenght of the buffer to be allocated
782 *
783 * RETURN     : int32_t type of status
784 *              NO_ERROR  -- success
785 *              none-zero failure code
786 *==========================================================================*/
787int QCameraHeapMemory::allocate(uint8_t count, size_t size, uint32_t isSecure)
788{
789    int rc = -1;
790    ATRACE_BEGIN_SNPRINTF("%s %zu %d", "HeapMemsize", size, count);
791    uint32_t heap_id_mask = 0x1 << ION_IOMMU_HEAP_ID;
792    if (isSecure == SECURE) {
793        rc = alloc(count, size, heap_id_mask, SECURE);
794        if (rc < 0) {
795            ATRACE_END();
796            return rc;
797        }
798    } else {
799        rc = alloc(count, size, heap_id_mask, NON_SECURE);
800        if (rc < 0) {
801            ATRACE_END();
802            return rc;
803        }
804
805        for (int i = 0; i < count; i ++) {
806            void *vaddr = mmap(NULL,
807                        mMemInfo[i].size,
808                        PROT_READ | PROT_WRITE,
809                        MAP_SHARED,
810                        mMemInfo[i].fd, 0);
811            if (vaddr == MAP_FAILED) {
812                for (int j = i-1; j >= 0; j --) {
813                    munmap(mPtr[j], mMemInfo[j].size);
814                    mPtr[j] = NULL;
815                    deallocOneBuffer(mMemInfo[j]);
816                }
817                // Deallocate remaining buffers that have already been allocated
818                for (int j = i; j < count; j++) {
819                    deallocOneBuffer(mMemInfo[j]);
820                }
821                ATRACE_END();
822                return NO_MEMORY;
823            } else
824                mPtr[i] = vaddr;
825        }
826    }
827    if (rc == 0) {
828        mBufferCount = count;
829    }
830    ATRACE_END();
831    return OK;
832}
833
834/*===========================================================================
835 * FUNCTION   : allocateMore
836 *
837 * DESCRIPTION: allocate more requested number of buffers of certain size
838 *
839 * PARAMETERS :
840 *   @count   : number of buffers to be allocated
841 *   @size    : lenght of the buffer to be allocated
842 *
843 * RETURN     : int32_t type of status
844 *              NO_ERROR  -- success
845 *              none-zero failure code
846 *==========================================================================*/
847int QCameraHeapMemory::allocateMore(uint8_t count, size_t size)
848{
849    ATRACE_BEGIN_SNPRINTF("%s %zu %d", "HeapMemsize", size, count);
850    unsigned int heap_id_mask = 0x1 << ION_IOMMU_HEAP_ID;
851    int rc = alloc(count, size, heap_id_mask, NON_SECURE);
852    if (rc < 0) {
853        ATRACE_END();
854        return rc;
855    }
856
857    for (int i = mBufferCount; i < count + mBufferCount; i ++) {
858        void *vaddr = mmap(NULL,
859                    mMemInfo[i].size,
860                    PROT_READ | PROT_WRITE,
861                    MAP_SHARED,
862                    mMemInfo[i].fd, 0);
863        if (vaddr == MAP_FAILED) {
864            for (int j = i-1; j >= mBufferCount; j --) {
865                munmap(mPtr[j], mMemInfo[j].size);
866                mPtr[j] = NULL;
867                deallocOneBuffer(mMemInfo[j]);
868            }
869            ATRACE_END();
870            return NO_MEMORY;
871        } else {
872            mPtr[i] = vaddr;
873        }
874    }
875    mBufferCount = (uint8_t)(mBufferCount + count);
876    ATRACE_END();
877    return OK;
878}
879
880/*===========================================================================
881 * FUNCTION   : deallocate
882 *
883 * DESCRIPTION: deallocate buffers
884 *
885 * PARAMETERS : none
886 *
887 * RETURN     : none
888 *==========================================================================*/
889void QCameraHeapMemory::deallocate()
890{
891    for (int i = 0; i < mBufferCount; i++) {
892        munmap(mPtr[i], mMemInfo[i].size);
893        mPtr[i] = NULL;
894    }
895    dealloc();
896    mBufferCount = 0;
897}
898
899/*===========================================================================
900 * FUNCTION   : cacheOps
901 *
902 * DESCRIPTION: ion related memory cache operations
903 *
904 * PARAMETERS :
905 *   @index   : index of the buffer
906 *   @cmd     : cache ops command
907 *
908 * RETURN     : int32_t type of status
909 *              NO_ERROR  -- success
910 *              none-zero failure code
911 *==========================================================================*/
912int QCameraHeapMemory::cacheOps(uint32_t index, unsigned int cmd)
913{
914    if (index >= mBufferCount)
915        return BAD_INDEX;
916    return cacheOpsInternal(index, cmd, mPtr[index]);
917}
918
919/*===========================================================================
920 * FUNCTION   : getRegFlags
921 *
922 * DESCRIPTION: query initial reg flags
923 *
924 * PARAMETERS :
925 *   @regFlags: initial reg flags of the allocated buffers
926 *
927 * RETURN     : int32_t type of status
928 *              NO_ERROR  -- success
929 *              none-zero failure code
930 *==========================================================================*/
931int QCameraHeapMemory::getRegFlags(uint8_t * /*regFlags*/) const
932{
933    return INVALID_OPERATION;
934}
935
936/*===========================================================================
937 * FUNCTION   : getMemory
938 *
939 * DESCRIPTION: get camera memory
940 *
941 * PARAMETERS :
942 *   @index   : buffer index
943 *   @metadata: flag if it's metadata
944 *
945 * RETURN     : camera memory ptr
946 *              NULL if not supported or failed
947 *==========================================================================*/
948camera_memory_t *QCameraHeapMemory::getMemory(uint32_t /*index*/, bool /*metadata*/) const
949{
950    return NULL;
951}
952
953/*===========================================================================
954 * FUNCTION   : getMatchBufIndex
955 *
956 * DESCRIPTION: query buffer index by opaque ptr
957 *
958 * PARAMETERS :
959 *   @opaque  : opaque ptr
960 *   @metadata: flag if it's metadata
961 *
962 * RETURN     : buffer index if match found,
963 *              -1 if failed
964 *==========================================================================*/
965int QCameraHeapMemory::getMatchBufIndex(const void *opaque,
966                                        bool metadata) const
967{
968    int index = -1;
969    if (metadata) {
970        return -1;
971    }
972    for (int i = 0; i < mBufferCount; i++) {
973        if (mPtr[i] == opaque) {
974            index = i;
975            break;
976        }
977    }
978    return index;
979}
980
981/*===========================================================================
982 * FUNCTION   : QCameraMetadataStreamMemory
983 *
984 * DESCRIPTION: constructor of QCameraMetadataStreamMemory
985 *              for ion memory used internally in HAL for metadata
986 *
987 * PARAMETERS :
988 *   @cached  : flag indicates if using cached memory
989 *
990 * RETURN     : none
991 *==========================================================================*/
992QCameraMetadataStreamMemory::QCameraMetadataStreamMemory(bool cached)
993    : QCameraHeapMemory(cached)
994{
995}
996
997/*===========================================================================
998 * FUNCTION   : ~QCameraMetadataStreamMemory
999 *
1000 * DESCRIPTION: destructor of QCameraMetadataStreamMemory
1001 *
1002 * PARAMETERS : none
1003 *
1004 * RETURN     : none
1005 *==========================================================================*/
1006QCameraMetadataStreamMemory::~QCameraMetadataStreamMemory()
1007{
1008    if (mBufferCount > 0) {
1009        LOGH("%s, buf_cnt > 0, deallocate buffers now.\n", __func__);
1010        deallocate();
1011    }
1012}
1013
1014/*===========================================================================
1015 * FUNCTION   : getRegFlags
1016 *
1017 * DESCRIPTION: query initial reg flags
1018 *
1019 * PARAMETERS :
1020 *   @regFlags: initial reg flags of the allocated buffers
1021 *
1022 * RETURN     : int32_t type of status
1023 *              NO_ERROR  -- success
1024 *              none-zero failure code
1025 *==========================================================================*/
1026int QCameraMetadataStreamMemory::getRegFlags(uint8_t *regFlags) const
1027{
1028    for (int i = 0; i < mBufferCount; i ++) {
1029        regFlags[i] = 1;
1030    }
1031    return NO_ERROR;
1032}
1033
1034/*===========================================================================
1035 * FUNCTION   : QCameraStreamMemory
1036 *
1037 * DESCRIPTION: constructor of QCameraStreamMemory
1038 *              ION memory allocated directly from /dev/ion and shared with framework
1039 *
1040 * PARAMETERS :
1041 *   @memory    : camera memory request ops table
1042 *   @cached    : flag indicates if using cached memory
1043 *
1044 * RETURN     : none
1045 *==========================================================================*/
1046QCameraStreamMemory::QCameraStreamMemory(camera_request_memory memory,
1047        bool cached,
1048        QCameraMemoryPool *pool,
1049        cam_stream_type_t streamType, __unused cam_stream_buf_type bufType)
1050    :QCameraMemory(cached, pool, streamType),
1051     mGetMemory(memory)
1052{
1053    for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i ++)
1054        mCameraMemory[i] = NULL;
1055}
1056
1057/*===========================================================================
1058 * FUNCTION   : ~QCameraStreamMemory
1059 *
1060 * DESCRIPTION: deconstructor of QCameraStreamMemory
1061 *
1062 * PARAMETERS : none
1063 *
1064 * RETURN     : none
1065 *==========================================================================*/
1066QCameraStreamMemory::~QCameraStreamMemory()
1067{
1068}
1069
1070/*===========================================================================
1071 * FUNCTION   : allocate
1072 *
1073 * DESCRIPTION: allocate requested number of buffers of certain size
1074 *
1075 * PARAMETERS :
1076 *   @count   : number of buffers to be allocated
1077 *   @size    : lenght of the buffer to be allocated
1078 *
1079 * RETURN     : int32_t type of status
1080 *              NO_ERROR  -- success
1081 *              none-zero failure code
1082 *==========================================================================*/
1083int QCameraStreamMemory::allocate(uint8_t count, size_t size, uint32_t isSecure)
1084{
1085    ATRACE_BEGIN_SNPRINTF("%s %zu %d", "StreamMemsize", size, count);
1086    unsigned int heap_id_mask = 0x1 << ION_IOMMU_HEAP_ID;
1087    int rc = alloc(count, size, heap_id_mask, isSecure);
1088    if (rc < 0) {
1089        ATRACE_END();
1090        return rc;
1091    }
1092
1093    for (int i = 0; i < count; i ++) {
1094        if (isSecure == SECURE) {
1095            mCameraMemory[i] = 0;
1096        } else {
1097            mCameraMemory[i] = mGetMemory(mMemInfo[i].fd, mMemInfo[i].size, 1, this);
1098        }
1099    }
1100    mBufferCount = count;
1101    ATRACE_END();
1102    return NO_ERROR;
1103}
1104
1105/*===========================================================================
1106 * FUNCTION   : allocateMore
1107 *
1108 * DESCRIPTION: allocate more requested number of buffers of certain size
1109 *
1110 * PARAMETERS :
1111 *   @count   : number of buffers to be allocated
1112 *   @size    : lenght of the buffer to be allocated
1113 *
1114 * RETURN     : int32_t type of status
1115 *              NO_ERROR  -- success
1116 *              none-zero failure code
1117 *==========================================================================*/
1118int QCameraStreamMemory::allocateMore(uint8_t count, size_t size)
1119{
1120    ATRACE_BEGIN_SNPRINTF("%s %zu %d", "StreamMemsize", size, count);
1121    unsigned int heap_id_mask = 0x1 << ION_IOMMU_HEAP_ID;
1122    int rc = alloc(count, size, heap_id_mask, NON_SECURE);
1123    if (rc < 0) {
1124        ATRACE_END();
1125        return rc;
1126    }
1127
1128    for (int i = mBufferCount; i < mBufferCount + count; i++) {
1129        mCameraMemory[i] = mGetMemory(mMemInfo[i].fd, mMemInfo[i].size, 1, this);
1130    }
1131    mBufferCount = (uint8_t)(mBufferCount + count);
1132    ATRACE_END();
1133    return NO_ERROR;
1134}
1135
1136/*===========================================================================
1137 * FUNCTION   : deallocate
1138 *
1139 * DESCRIPTION: deallocate buffers
1140 *
1141 * PARAMETERS : none
1142 *
1143 * RETURN     : none
1144 *==========================================================================*/
1145void QCameraStreamMemory::deallocate()
1146{
1147    for (int i = 0; i < mBufferCount; i ++) {
1148        if (mCameraMemory[i])
1149            mCameraMemory[i]->release(mCameraMemory[i]);
1150        mCameraMemory[i] = NULL;
1151    }
1152    dealloc();
1153    mBufferCount = 0;
1154}
1155
1156/*===========================================================================
1157 * FUNCTION   : cacheOps
1158 *
1159 * DESCRIPTION: ion related memory cache operations
1160 *
1161 * PARAMETERS :
1162 *   @index   : index of the buffer
1163 *   @cmd     : cache ops command
1164 *
1165 * RETURN     : int32_t type of status
1166 *              NO_ERROR  -- success
1167 *              none-zero failure code
1168 *==========================================================================*/
1169int QCameraStreamMemory::cacheOps(uint32_t index, unsigned int cmd)
1170{
1171    if (index >= mBufferCount)
1172        return BAD_INDEX;
1173    return cacheOpsInternal(index, cmd, mCameraMemory[index]->data);
1174}
1175
1176/*===========================================================================
1177 * FUNCTION   : getRegFlags
1178 *
1179 * DESCRIPTION: query initial reg flags
1180 *
1181 * PARAMETERS :
1182 *   @regFlags: initial reg flags of the allocated buffers
1183 *
1184 * RETURN     : int32_t type of status
1185 *              NO_ERROR  -- success
1186 *              none-zero failure code
1187 *==========================================================================*/
1188int QCameraStreamMemory::getRegFlags(uint8_t *regFlags) const
1189{
1190    for (int i = 0; i < mBufferCount; i ++)
1191        regFlags[i] = 1;
1192    return NO_ERROR;
1193}
1194
1195/*===========================================================================
1196 * FUNCTION   : getMemory
1197 *
1198 * DESCRIPTION: get camera memory
1199 *
1200 * PARAMETERS :
1201 *   @index   : buffer index
1202 *   @metadata: flag if it's metadata
1203 *
1204 * RETURN     : camera memory ptr
1205 *              NULL if not supported or failed
1206 *==========================================================================*/
1207camera_memory_t *QCameraStreamMemory::getMemory(uint32_t index,
1208        bool metadata) const
1209{
1210    if (index >= mBufferCount || metadata)
1211        return NULL;
1212    return mCameraMemory[index];
1213}
1214
1215/*===========================================================================
1216 * FUNCTION   : getMatchBufIndex
1217 *
1218 * DESCRIPTION: query buffer index by opaque ptr
1219 *
1220 * PARAMETERS :
1221 *   @opaque  : opaque ptr
1222 *   @metadata: flag if it's metadata
1223 *
1224 * RETURN     : buffer index if match found,
1225 *              -1 if failed
1226 *==========================================================================*/
1227int QCameraStreamMemory::getMatchBufIndex(const void *opaque,
1228                                          bool metadata) const
1229{
1230    int index = -1;
1231    if (metadata) {
1232        return -1;
1233    }
1234    for (int i = 0; i < mBufferCount; i++) {
1235        if (mCameraMemory[i]->data == opaque) {
1236            index = i;
1237            break;
1238        }
1239    }
1240    return index;
1241}
1242
1243/*===========================================================================
1244 * FUNCTION   : getPtr
1245 *
1246 * DESCRIPTION: return buffer pointer
1247 *
1248 * PARAMETERS :
1249 *   @index   : index of the buffer
1250 *
1251 * RETURN     : buffer ptr
1252 *==========================================================================*/
1253void *QCameraStreamMemory::getPtr(uint32_t index) const
1254{
1255    if (index >= mBufferCount) {
1256        LOGE("index out of bound");
1257        return (void *)BAD_INDEX;
1258    }
1259    if (mCameraMemory[index] == 0) {
1260        return NULL;
1261    }
1262    return mCameraMemory[index]->data;
1263}
1264
1265/*===========================================================================
1266 * FUNCTION   : QCameraVideoMemory
1267 *
1268 * DESCRIPTION: constructor of QCameraVideoMemory
1269 *              VideoStream buffers also include metadata buffers
1270 *
1271 * PARAMETERS :
1272 *   @memory    : camera memory request ops table
1273 *   @cached    : flag indicates if using cached ION memory
1274 *
1275 * RETURN     : none
1276 *==========================================================================*/
1277QCameraVideoMemory::QCameraVideoMemory(camera_request_memory memory,
1278                                       bool cached, QCameraMemType bufType)
1279    : QCameraStreamMemory(memory, cached)
1280{
1281    memset(mMetadata, 0, sizeof(mMetadata));
1282    mMetaBufCount = 0;
1283    mBufType = bufType;
1284    //Set Default color conversion format
1285    mUsage = private_handle_t::PRIV_FLAGS_ITU_R_709;
1286
1287    //Set Default frame format
1288    mFormat = OMX_COLOR_FormatYUV420SemiPlanar;
1289}
1290
1291/*===========================================================================
1292 * FUNCTION   : ~QCameraVideoMemory
1293 *
1294 * DESCRIPTION: deconstructor of QCameraVideoMemory
1295 *
1296 * PARAMETERS : none
1297 *
1298 * RETURN     : none
1299 *==========================================================================*/
1300QCameraVideoMemory::~QCameraVideoMemory()
1301{
1302}
1303
1304/*===========================================================================
1305 * FUNCTION   : allocate
1306 *
1307 * DESCRIPTION: allocate requested number of buffers of certain size
1308 *
1309 * PARAMETERS :
1310 *   @count   : number of buffers to be allocated
1311 *   @size    : lenght of the buffer to be allocated
1312 *
1313 * RETURN     : int32_t type of status
1314 *              NO_ERROR  -- success
1315 *              none-zero failure code
1316 *==========================================================================*/
1317int QCameraVideoMemory::allocate(uint8_t count, size_t size, uint32_t isSecure)
1318{
1319    ATRACE_BEGIN_SNPRINTF("%s %zu %d", "VideoMemsize", size, count);
1320    int rc = QCameraStreamMemory::allocate(count, size, isSecure);
1321    if (rc < 0) {
1322        ATRACE_END();
1323        return rc;
1324    }
1325
1326    if (!(mBufType & QCAMERA_MEM_TYPE_BATCH)) {
1327        /*
1328        *    FDs = 1
1329        *    numInts  = 5 //offset, size, usage, timestamp, format
1330        */
1331        rc = allocateMeta(count, 1, VIDEO_METADATA_NUM_INTS);
1332        if (rc != NO_ERROR) {
1333            ATRACE_END();
1334            return rc;
1335        }
1336        for (int i = 0; i < count; i ++) {
1337            struct encoder_media_buffer_type * packet =
1338                    (struct encoder_media_buffer_type *)mMetadata[i]->data;
1339            native_handle_t * nh = const_cast<native_handle_t *>(packet->meta_handle);
1340            if (!nh) {
1341                LOGE("Error in getting video native handle");
1342                ATRACE_END();
1343                return NO_MEMORY;
1344            }
1345            nh->data[0] = mMemInfo[i].fd;
1346            nh->data[1] = 0;
1347            nh->data[2] = (int)mMemInfo[i].size;
1348            nh->data[3] = mUsage;
1349            nh->data[4] = 0; //dummy value for timestamp in non-batch mode
1350            nh->data[5] = mFormat;
1351        }
1352    }
1353    mBufferCount = count;
1354    ATRACE_END();
1355    return NO_ERROR;
1356}
1357
1358/*===========================================================================
1359 * FUNCTION   : allocateMore
1360 *
1361 * DESCRIPTION: allocate more requested number of buffers of certain size
1362 *
1363 * PARAMETERS :
1364 *   @count   : number of buffers to be allocated
1365 *   @size    : lenght of the buffer to be allocated
1366 *
1367 * RETURN     : int32_t type of status
1368 *              NO_ERROR  -- success
1369 *              none-zero failure code
1370 *==========================================================================*/
1371int QCameraVideoMemory::allocateMore(uint8_t count, size_t size)
1372{
1373    ATRACE_BEGIN_SNPRINTF("%s %zu %d", "VideoMemsize", size, count);
1374    int rc = QCameraStreamMemory::allocateMore(count, size);
1375    if (rc < 0) {
1376        ATRACE_END();
1377        return rc;
1378    }
1379
1380    if (!(mBufType & QCAMERA_MEM_TYPE_BATCH)) {
1381        for (int i = mBufferCount; i < count + mBufferCount; i ++) {
1382            mMetadata[i] = mGetMemory(-1,
1383                    sizeof(struct encoder_media_buffer_type), 1, this);
1384            if (!mMetadata[i]) {
1385                LOGE("allocation of video metadata failed.");
1386                for (int j = mBufferCount; j <= i-1; j ++) {
1387                    mMetadata[j]->release(mMetadata[j]);
1388                    mCameraMemory[j]->release(mCameraMemory[j]);
1389                    mCameraMemory[j] = NULL;
1390                    deallocOneBuffer(mMemInfo[j]);;
1391                }
1392                ATRACE_END();
1393                return NO_MEMORY;
1394            }
1395            struct encoder_media_buffer_type * packet =
1396                    (struct encoder_media_buffer_type *)mMetadata[i]->data;
1397
1398            //FDs = 1
1399            //numInts  = 5 (offset, size, usage, timestamp, format)
1400            packet->meta_handle = native_handle_create(1, VIDEO_METADATA_NUM_INTS);
1401            packet->buffer_type = kMetadataBufferTypeCameraSource;
1402            native_handle_t * nh = const_cast<native_handle_t *>(packet->meta_handle);
1403            if (!nh) {
1404                LOGE("Error in getting video native handle");
1405                ATRACE_END();
1406                return NO_MEMORY;
1407            }
1408            nh->data[0] = mMemInfo[i].fd;
1409            nh->data[1] = 0;
1410            nh->data[2] = (int)mMemInfo[i].size;
1411            nh->data[3] = mUsage;
1412            nh->data[4] = 0; //dummy value for timestamp in non-batch mode
1413            nh->data[5] = mFormat;
1414        }
1415    }
1416    mBufferCount = (uint8_t)(mBufferCount + count);
1417    mMetaBufCount = mBufferCount;
1418    ATRACE_END();
1419    return NO_ERROR;
1420}
1421
1422/*===========================================================================
1423 * FUNCTION   : allocateMeta
1424 *
1425 * DESCRIPTION: allocate video encoder metadata structure
1426 *
1427 * PARAMETERS :
1428 *   @fd_cnt : Total FD count
1429 *
1430 * RETURN     : int32_t type of status
1431 *              NO_ERROR  -- success
1432 *              none-zero failure code
1433 *==========================================================================*/
1434int QCameraVideoMemory::allocateMeta(uint8_t buf_cnt, int numFDs, int numInts)
1435{
1436    int rc = NO_ERROR;
1437
1438    for (int i = 0; i < buf_cnt; i++) {
1439        mMetadata[i] = mGetMemory(-1,
1440                sizeof(struct encoder_media_buffer_type), 1, this);
1441        if (!mMetadata[i]) {
1442            LOGE("allocation of video metadata failed.");
1443            for (int j = (i - 1); j >= 0; j--) {
1444                mMetadata[j]->release(mMetadata[j]);
1445            }
1446            return NO_MEMORY;
1447        }
1448        struct encoder_media_buffer_type * packet =
1449                (struct encoder_media_buffer_type *)mMetadata[i]->data;
1450        packet->meta_handle = native_handle_create(numFDs, (numInts * numFDs));
1451        packet->buffer_type = kMetadataBufferTypeCameraSource;
1452        if (packet->meta_handle == NULL) {
1453            LOGE("Error in getting video native handle");
1454            for (int j = (i - 1); j >= 0; j--) {
1455                mMetadata[j]->release(mMetadata[j]);
1456            }
1457            return NO_MEMORY;
1458        }
1459    }
1460    mMetaBufCount = buf_cnt;
1461    return rc;
1462}
1463
1464/*===========================================================================
1465 * FUNCTION   : deallocateMeta
1466 *
1467 * DESCRIPTION: deallocate video metadata buffers
1468 *
1469 * PARAMETERS : none
1470 *
1471 * RETURN     : none
1472 *==========================================================================*/
1473void QCameraVideoMemory::deallocateMeta()
1474{
1475    for (int i = 0; i < mMetaBufCount; i++) {
1476        struct encoder_media_buffer_type * packet =
1477                (struct encoder_media_buffer_type *)mMetadata[i]->data;
1478        if (NULL != packet) {
1479            native_handle_t * nh = const_cast<native_handle_t *>(packet->meta_handle);
1480            if (NULL != nh) {
1481               if (native_handle_delete(nh)) {
1482                   LOGE("Unable to delete native handle");
1483               }
1484            } else {
1485               LOGE("native handle not available");
1486            }
1487        } else {
1488            LOGE("packet not available");
1489        }
1490        mMetadata[i]->release(mMetadata[i]);
1491        mMetadata[i] = NULL;
1492    }
1493    mMetaBufCount = 0;
1494}
1495
1496
1497/*===========================================================================
1498 * FUNCTION   : deallocate
1499 *
1500 * DESCRIPTION: deallocate buffers
1501 *
1502 * PARAMETERS : none
1503 *
1504 * RETURN     : none
1505 *==========================================================================*/
1506void QCameraVideoMemory::deallocate()
1507{
1508    deallocateMeta();
1509
1510    QCameraStreamMemory::deallocate();
1511    mBufferCount = 0;
1512    mMetaBufCount = 0;
1513}
1514
1515/*===========================================================================
1516 * FUNCTION   : getMemory
1517 *
1518 * DESCRIPTION: get camera memory
1519 *
1520 * PARAMETERS :
1521 *   @index   : buffer index
1522 *   @metadata: flag if it's metadata
1523 *
1524 * RETURN     : camera memory ptr
1525 *              NULL if not supported or failed
1526 *==========================================================================*/
1527camera_memory_t *QCameraVideoMemory::getMemory(uint32_t index,
1528        bool metadata) const
1529{
1530    if (index >= mMetaBufCount || (!metadata && index >= mBufferCount))
1531        return NULL;
1532
1533    if (metadata)
1534        return mMetadata[index];
1535    else
1536        return mCameraMemory[index];
1537}
1538
1539/*===========================================================================
1540 * FUNCTION   : getMatchBufIndex
1541 *
1542 * DESCRIPTION: query buffer index by opaque ptr
1543 *
1544 * PARAMETERS :
1545 *   @opaque  : opaque ptr
1546 *   @metadata: flag if it's metadata
1547 *
1548 * RETURN     : buffer index if match found,
1549 *              -1 if failed
1550 *==========================================================================*/
1551int QCameraVideoMemory::getMatchBufIndex(const void *opaque,
1552                                         bool metadata) const
1553{
1554    int index = -1;
1555
1556    if (metadata) {
1557        for (int i = 0; i < mMetaBufCount; i++) {
1558            if (mMetadata[i]->data == opaque) {
1559                index = i;
1560                break;
1561            }
1562        }
1563    } else {
1564        for (int i = 0; i < mBufferCount; i++) {
1565            if (mCameraMemory[i]->data == opaque) {
1566                index = i;
1567                break;
1568            }
1569        }
1570    }
1571    return index;
1572}
1573
1574/*===========================================================================
1575 * FUNCTION   : setVideoInfo
1576 *
1577 * DESCRIPTION: set native window gralloc ops table
1578 *
1579 * PARAMETERS :
1580 *   @usage : usage bit for video
1581 *
1582 * RETURN     : none
1583 *==========================================================================*/
1584void QCameraVideoMemory::setVideoInfo(int usage, cam_format_t format)
1585{
1586    mUsage |= usage;
1587    mFormat = convCamtoOMXFormat(format);
1588}
1589
1590/*===========================================================================
1591 * FUNCTION   : convCamtoOMXFormat
1592 *
1593 * DESCRIPTION: map cam_format_t to corresponding OMX format
1594 *
1595 * PARAMETERS :
1596 *   @format : format in cam_format_t type
1597 *
1598 * RETURN     : omx format
1599 *==========================================================================*/
1600int QCameraVideoMemory::convCamtoOMXFormat(cam_format_t format)
1601{
1602    int omxFormat = OMX_COLOR_FormatYUV420SemiPlanar;
1603    switch (format) {
1604        case CAM_FORMAT_YUV_420_NV21:
1605        case CAM_FORMAT_YUV_420_NV21_VENUS:
1606        case CAM_FORMAT_YUV_420_NV21_ADRENO:
1607            omxFormat = QOMX_COLOR_FormatYVU420SemiPlanar;
1608            break;
1609        case CAM_FORMAT_YUV_420_NV12:
1610        case CAM_FORMAT_YUV_420_NV12_VENUS:
1611            omxFormat = OMX_COLOR_FormatYUV420SemiPlanar;
1612            break;
1613#ifndef VANILLA_HAL
1614        case CAM_FORMAT_YUV_420_NV12_UBWC:
1615            omxFormat = QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed;
1616            break;
1617#endif
1618        default:
1619            omxFormat = OMX_COLOR_FormatYUV420SemiPlanar;
1620    }
1621    return omxFormat;
1622}
1623
1624/*===========================================================================
1625 * FUNCTION   : QCameraGrallocMemory
1626 *
1627 * DESCRIPTION: constructor of QCameraGrallocMemory
1628 *              preview stream buffers are allocated from gralloc native_windoe
1629 *
1630 * PARAMETERS :
1631 *   @memory    : camera memory request ops table
1632 *
1633 * RETURN     : none
1634 *==========================================================================*/
1635QCameraGrallocMemory::QCameraGrallocMemory(camera_request_memory memory)
1636        : QCameraMemory(true), mColorSpace(ITU_R_601_FR)
1637{
1638    mMinUndequeuedBuffers = 0;
1639    mMappableBuffers = 0;
1640    mWindow = NULL;
1641    mWidth = mHeight = mStride = mScanline = mUsage = 0;
1642    mFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
1643    mGetMemory = memory;
1644    for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i ++) {
1645        mBufferHandle[i] = NULL;
1646        mLocalFlag[i] = BUFFER_NOT_OWNED;
1647        mPrivateHandle[i] = NULL;
1648    }
1649}
1650
1651/*===========================================================================
1652 * FUNCTION   : ~QCameraGrallocMemory
1653 *
1654 * DESCRIPTION: deconstructor of QCameraGrallocMemory
1655 *
1656 * PARAMETERS : none
1657 *
1658 * RETURN     : none
1659 *==========================================================================*/
1660QCameraGrallocMemory::~QCameraGrallocMemory()
1661{
1662}
1663
1664/*===========================================================================
1665 * FUNCTION   : setWindowInfo
1666 *
1667 * DESCRIPTION: set native window gralloc ops table
1668 *
1669 * PARAMETERS :
1670 *   @window  : gralloc ops table ptr
1671 *   @width   : width of preview frame
1672 *   @height  : height of preview frame
1673 *   @stride  : stride of preview frame
1674 *   @scanline: scanline of preview frame
1675 *   @foramt  : format of preview image
1676 *   @maxFPS : max fps of preview stream
1677 *   @usage : usage bit for gralloc
1678 *
1679 * RETURN     : none
1680 *==========================================================================*/
1681void QCameraGrallocMemory::setWindowInfo(preview_stream_ops_t *window,
1682        int width, int height, int stride, int scanline, int format, int maxFPS, int usage)
1683{
1684    mWindow = window;
1685    mWidth = width;
1686    mHeight = height;
1687    mStride = stride;
1688    mScanline = scanline;
1689    mFormat = format;
1690    mUsage = usage;
1691    setMaxFPS(maxFPS);
1692}
1693
1694/*===========================================================================
1695 * FUNCTION   : setMaxFPS
1696 *
1697 * DESCRIPTION: set max fps
1698 *
1699 * PARAMETERS :
1700 *   @maxFPS : max fps of preview stream
1701 *
1702 * RETURN     : none
1703 *==========================================================================*/
1704void QCameraGrallocMemory::setMaxFPS(int maxFPS)
1705{
1706    /* input will be in multiples of 1000 */
1707    maxFPS = (maxFPS + 500)/1000;
1708
1709    /* set the lower cap to 30 always, because we are not supporting runtime update of fps info
1710      to display. Otherwise MDP may result in underruns (for example if initial fps is 15max and later
1711      changed to 30).*/
1712    if (maxFPS < 30) {
1713        maxFPS = 30;
1714    }
1715
1716    /* the new fps will be updated in metadata of the next frame enqueued to display*/
1717    mMaxFPS = maxFPS;
1718    LOGH("Setting max fps %d to display", mMaxFPS);
1719}
1720
1721/*===========================================================================
1722 * FUNCTION   : displayBuffer
1723 *
1724 * DESCRIPTION: send received frame to display
1725 *
1726 * PARAMETERS :
1727 *   @index   : index of preview frame
1728 *
1729 * RETURN     : int32_t type of status
1730 *              NO_ERROR  -- success
1731 *              none-zero failure code
1732 *==========================================================================*/
1733int QCameraGrallocMemory::displayBuffer(uint32_t index)
1734{
1735    int err = NO_ERROR;
1736    int dequeuedIdx = BAD_INDEX;
1737
1738    if (BUFFER_NOT_OWNED == mLocalFlag[index]) {
1739        LOGE("buffer to be enqueued is not owned");
1740        return INVALID_OPERATION;
1741    }
1742
1743    err = mWindow->enqueue_buffer(mWindow, (buffer_handle_t *)mBufferHandle[index]);
1744    if(err != 0) {
1745        LOGE("enqueue_buffer failed, err = %d", err);
1746    } else {
1747        LOGD("enqueue_buffer hdl=%p", *mBufferHandle[index]);
1748        mLocalFlag[index] = BUFFER_NOT_OWNED;
1749    }
1750
1751    buffer_handle_t *buffer_handle = NULL;
1752    int stride = 0;
1753    err = mWindow->dequeue_buffer(mWindow, &buffer_handle, &stride);
1754    if (err == NO_ERROR && buffer_handle != NULL) {
1755        int i;
1756        LOGD("dequed buf hdl =%p", *buffer_handle);
1757        for(i = 0; i < mMappableBuffers; i++) {
1758            if(mBufferHandle[i] == buffer_handle) {
1759                LOGD("Found buffer in idx:%d", i);
1760                mLocalFlag[i] = BUFFER_OWNED;
1761                dequeuedIdx = i;
1762                break;
1763            }
1764        }
1765
1766        if ((dequeuedIdx == BAD_INDEX) && (mMappableBuffers < mBufferCount)) {
1767            dequeuedIdx = mMappableBuffers;
1768            LOGD("Placing buffer in idx:%d", dequeuedIdx);
1769            mBufferHandle[dequeuedIdx] = buffer_handle;
1770            mLocalFlag[dequeuedIdx] = BUFFER_OWNED;
1771
1772            mPrivateHandle[dequeuedIdx] =
1773                    (struct private_handle_t *)(*mBufferHandle[dequeuedIdx]);
1774            mMemInfo[dequeuedIdx].main_ion_fd = open("/dev/ion", O_RDONLY);
1775            if (mMemInfo[dequeuedIdx].main_ion_fd < 0) {
1776                LOGE("failed: could not open ion device");
1777                return BAD_INDEX;
1778            }
1779
1780            struct ion_fd_data ion_info_fd;
1781            memset(&ion_info_fd, 0, sizeof(ion_info_fd));
1782            ion_info_fd.fd = mPrivateHandle[dequeuedIdx]->fd;
1783            if (ioctl(mMemInfo[dequeuedIdx].main_ion_fd,
1784                      ION_IOC_IMPORT, &ion_info_fd) < 0) {
1785                LOGE("ION import failed\n");
1786                return BAD_INDEX;
1787            }
1788
1789            mCameraMemory[dequeuedIdx] =
1790                    mGetMemory(mPrivateHandle[dequeuedIdx]->fd,
1791                    (size_t)mPrivateHandle[dequeuedIdx]->size,
1792                    1,
1793                    (void *)this);
1794            LOGH("idx = %d, fd = %d, size = %d, offset = %d",
1795                     dequeuedIdx, mPrivateHandle[dequeuedIdx]->fd,
1796                    mPrivateHandle[dequeuedIdx]->size,
1797                    mPrivateHandle[dequeuedIdx]->offset);
1798            mMemInfo[dequeuedIdx].fd = mPrivateHandle[dequeuedIdx]->fd;
1799            mMemInfo[dequeuedIdx].size =
1800                    (size_t)mPrivateHandle[dequeuedIdx]->size;
1801            mMemInfo[dequeuedIdx].handle = ion_info_fd.handle;
1802
1803            mMappableBuffers++;
1804        }
1805    } else {
1806        LOGW("dequeue_buffer, no free buffer from display now");
1807    }
1808    return dequeuedIdx;
1809}
1810
1811/*===========================================================================
1812 * FUNCTION   : enqueueBuffer
1813 *
1814 * DESCRIPTION: enqueue camera frame to display
1815 *
1816 * PARAMETERS :
1817 *   @index   : index of frame
1818 *   @timeStamp : frame presentation time
1819 *
1820 * RETURN     : int32_t type of status
1821 *              NO_ERROR  -- success
1822 *              none-zero failure code
1823 *==========================================================================*/
1824int32_t QCameraGrallocMemory::enqueueBuffer(uint32_t index, nsecs_t timeStamp)
1825{
1826    int32_t err = NO_ERROR;
1827
1828    if (BUFFER_NOT_OWNED == mLocalFlag[index]) {
1829        LOGE("buffer to be enqueued is not owned");
1830        return INVALID_OPERATION;
1831    }
1832
1833    if (timeStamp != 0) {
1834        err = mWindow->set_timestamp(mWindow, timeStamp);
1835        if (err != NO_ERROR){
1836            LOGE("Failed to native window timestamp");
1837        }
1838    }
1839
1840    err = mWindow->enqueue_buffer(mWindow, (buffer_handle_t *)mBufferHandle[index]);
1841    if(err != 0) {
1842        LOGE("enqueue_buffer failed, err = %d", err);
1843    } else {
1844        LOGD("enqueue_buffer hdl=%p", *mBufferHandle[index]);
1845        mLocalFlag[index] = BUFFER_NOT_OWNED;
1846    }
1847    return err;
1848}
1849
1850/*===========================================================================
1851 * FUNCTION   : dequeueBuffer
1852 *
1853 * DESCRIPTION: receive a buffer from gralloc
1854 *
1855 * PARAMETERS : None
1856 *
1857 * RETURN     : int32_t
1858 *              NO_ERROR/Buffer index : Success
1859 *              < 0 failure code
1860 *==========================================================================*/
1861int32_t QCameraGrallocMemory::dequeueBuffer()
1862{
1863    int32_t err = NO_ERROR;
1864    int32_t dequeuedIdx = BAD_INDEX;
1865    buffer_handle_t *buffer_handle = NULL;
1866    int32_t stride = 0;
1867
1868    dequeuedIdx = BAD_INDEX;
1869    err = mWindow->dequeue_buffer(mWindow, &buffer_handle, &stride);
1870    if ((err == NO_ERROR) && (buffer_handle != NULL)) {
1871        int i;
1872        LOGD("dequed buf hdl =%p", *buffer_handle);
1873        for(i = 0; i < mMappableBuffers; i++) {
1874            if(mBufferHandle[i] == buffer_handle) {
1875                LOGD("Found buffer in idx:%d", i);
1876                mLocalFlag[i] = BUFFER_OWNED;
1877                dequeuedIdx = i;
1878                break;
1879            }
1880        }
1881
1882        if ((dequeuedIdx == BAD_INDEX) &&
1883                (mMappableBuffers < mBufferCount)) {
1884            dequeuedIdx = mMappableBuffers;
1885            LOGD("Placing buffer in idx:%d", dequeuedIdx);
1886            mBufferHandle[dequeuedIdx] = buffer_handle;
1887            mLocalFlag[dequeuedIdx] = BUFFER_OWNED;
1888
1889            mPrivateHandle[dequeuedIdx] =
1890                    (struct private_handle_t *)(*mBufferHandle[dequeuedIdx]);
1891            //update max fps info
1892            setMetaData(mPrivateHandle[dequeuedIdx], UPDATE_REFRESH_RATE, (void*)&mMaxFPS);
1893            mMemInfo[dequeuedIdx].main_ion_fd = open("/dev/ion", O_RDONLY);
1894            if (mMemInfo[dequeuedIdx].main_ion_fd < 0) {
1895                LOGE("failed: could not open ion device");
1896                return BAD_INDEX;
1897            }
1898
1899            struct ion_fd_data ion_info_fd;
1900            memset(&ion_info_fd, 0, sizeof(ion_info_fd));
1901            ion_info_fd.fd = mPrivateHandle[dequeuedIdx]->fd;
1902            if (ioctl(mMemInfo[dequeuedIdx].main_ion_fd,
1903                    ION_IOC_IMPORT, &ion_info_fd) < 0) {
1904                LOGE("ION import failed\n");
1905                return BAD_INDEX;
1906            }
1907
1908            setMetaData(mPrivateHandle[dequeuedIdx], UPDATE_COLOR_SPACE,
1909                    &mColorSpace);
1910            mCameraMemory[dequeuedIdx] =
1911                    mGetMemory(mPrivateHandle[dequeuedIdx]->fd,
1912                    (size_t)mPrivateHandle[dequeuedIdx]->size,
1913                    1,
1914                    (void *)this);
1915            LOGH("idx = %d, fd = %d, size = %d, offset = %d",
1916                     dequeuedIdx, mPrivateHandle[dequeuedIdx]->fd,
1917                    mPrivateHandle[dequeuedIdx]->size,
1918                    mPrivateHandle[dequeuedIdx]->offset);
1919            mMemInfo[dequeuedIdx].fd = mPrivateHandle[dequeuedIdx]->fd;
1920            mMemInfo[dequeuedIdx].size =
1921                    (size_t)mPrivateHandle[dequeuedIdx]->size;
1922            mMemInfo[dequeuedIdx].handle = ion_info_fd.handle;
1923
1924            mMappableBuffers++;
1925        }
1926    } else {
1927        LOGW("dequeue_buffer, no free buffer from display now");
1928    }
1929
1930    return dequeuedIdx;
1931}
1932
1933
1934/*===========================================================================
1935 * FUNCTION   : allocate
1936 *
1937 * DESCRIPTION: allocate requested number of buffers of certain size
1938 *
1939 * PARAMETERS :
1940 *   @count   : number of buffers to be allocated
1941 *   @size    : lenght of the buffer to be allocated
1942 *
1943 * RETURN     : int32_t type of status
1944 *              NO_ERROR  -- success
1945 *              none-zero failure code
1946 *==========================================================================*/
1947int QCameraGrallocMemory::allocate(uint8_t count, size_t /*size*/,
1948        uint32_t /*isSecure*/)
1949{
1950    ATRACE_BEGIN_SNPRINTF("%s %d", "Grallocbufcnt", count);
1951    int err = 0;
1952    status_t ret = NO_ERROR;
1953    int gralloc_usage = 0;
1954    struct ion_fd_data ion_info_fd;
1955    memset(&ion_info_fd, 0, sizeof(ion_info_fd));
1956
1957    LOGD("E ");
1958
1959    if (!mWindow) {
1960        LOGE("Invalid native window");
1961        ATRACE_END();
1962        ret = INVALID_OPERATION;
1963        goto end;
1964    }
1965
1966    // Increment buffer count by min undequeued buffer.
1967    err = mWindow->get_min_undequeued_buffer_count(mWindow,&mMinUndequeuedBuffers);
1968    if (err != 0) {
1969        LOGE("get_min_undequeued_buffer_count  failed: %s (%d)",
1970                strerror(-err), -err);
1971        ret = UNKNOWN_ERROR;
1972        goto end;
1973    }
1974
1975    err = mWindow->set_buffer_count(mWindow, count);
1976    if (err != 0) {
1977         LOGE("set_buffer_count failed: %s (%d)",
1978                    strerror(-err), -err);
1979         ret = UNKNOWN_ERROR;
1980         goto end;
1981    }
1982
1983    err = mWindow->set_buffers_geometry(mWindow, mStride, mScanline, mFormat);
1984    if (err != 0) {
1985         LOGE("set_buffers_geometry failed: %s (%d)",
1986                strerror(-err), -err);
1987         ret = UNKNOWN_ERROR;
1988         goto end;
1989    }
1990
1991    err = mWindow->set_crop(mWindow, 0, 0, mWidth, mHeight);
1992    if (err != 0) {
1993         LOGE("set_crop failed: %s (%d)",
1994                strerror(-err), -err);
1995         ret = UNKNOWN_ERROR;
1996         goto end;
1997    }
1998
1999    gralloc_usage = GRALLOC_USAGE_HW_CAMERA_WRITE;
2000    gralloc_usage |= mUsage;
2001    err = mWindow->set_usage(mWindow, gralloc_usage);
2002    if(err != 0) {
2003        /* set_usage error out */
2004        LOGE("set_usage rc = %d", err);
2005        ret = UNKNOWN_ERROR;
2006        goto end;
2007    }
2008    LOGH("usage = %d, geometry: %p, %d, %d, %d, %d, %d",
2009           gralloc_usage, mWindow, mWidth, mHeight, mStride,
2010          mScanline, mFormat);
2011
2012    mBufferCount = count;
2013    if ((count < mMappableBuffers) || (mMappableBuffers == 0)) {
2014        mMappableBuffers = count;
2015    }
2016
2017    //Allocate cnt number of buffers from native window
2018    for (int cnt = 0; cnt < mMappableBuffers; cnt++) {
2019        int stride;
2020        err = mWindow->dequeue_buffer(mWindow, &mBufferHandle[cnt], &stride);
2021        if(!err) {
2022            LOGD("dequeue buf hdl =%p", mBufferHandle[cnt]);
2023            mLocalFlag[cnt] = BUFFER_OWNED;
2024        } else {
2025            mLocalFlag[cnt] = BUFFER_NOT_OWNED;
2026            LOGE("dequeue_buffer idx = %d err = %d", cnt, err);
2027        }
2028
2029        LOGD("dequeue buf: %p\n", mBufferHandle[cnt]);
2030
2031        if(err != 0) {
2032            LOGE("dequeue_buffer failed: %s (%d)",
2033                   strerror(-err), -err);
2034            ret = UNKNOWN_ERROR;
2035            for(int i = 0; i < cnt; i++) {
2036                // Deallocate buffers when the native window is gone
2037                struct ion_handle_data ion_handle;
2038                memset(&ion_handle, 0, sizeof(ion_handle));
2039                ion_handle.handle = mMemInfo[i].handle;
2040                if (ioctl(mMemInfo[i].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) {
2041                    ALOGE("ion free failed");
2042                }
2043                close(mMemInfo[i].main_ion_fd);
2044
2045                if(mLocalFlag[i] != BUFFER_NOT_OWNED) {
2046                    err = mWindow->cancel_buffer(mWindow, mBufferHandle[i]);
2047                    LOGH("cancel_buffer: hdl =%p", (*mBufferHandle[i]));
2048                }
2049                mLocalFlag[i] = BUFFER_NOT_OWNED;
2050                mBufferHandle[i] = NULL;
2051            }
2052            reset();
2053            goto end;
2054        }
2055
2056        mPrivateHandle[cnt] =
2057            (struct private_handle_t *)(*mBufferHandle[cnt]);
2058        //update max fps info
2059        setMetaData(mPrivateHandle[cnt], UPDATE_REFRESH_RATE, (void*)&mMaxFPS);
2060        mMemInfo[cnt].main_ion_fd = open("/dev/ion", O_RDONLY);
2061        if (mMemInfo[cnt].main_ion_fd < 0) {
2062            LOGE("failed: could not open ion device");
2063            for(int i = 0; i < cnt; i++) {
2064                struct ion_handle_data ion_handle;
2065                memset(&ion_handle, 0, sizeof(ion_handle));
2066                ion_handle.handle = mMemInfo[i].handle;
2067                if (ioctl(mMemInfo[i].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) {
2068                    LOGE("ion free failed");
2069                }
2070                close(mMemInfo[i].main_ion_fd);
2071                if(mLocalFlag[i] != BUFFER_NOT_OWNED) {
2072                    err = mWindow->cancel_buffer(mWindow, mBufferHandle[i]);
2073                    LOGH("cancel_buffer: hdl =%p", (*mBufferHandle[i]));
2074                }
2075                mLocalFlag[i] = BUFFER_NOT_OWNED;
2076                mBufferHandle[i] = NULL;
2077            }
2078            reset();
2079            ret = UNKNOWN_ERROR;
2080            goto end;
2081        } else {
2082            ion_info_fd.fd = mPrivateHandle[cnt]->fd;
2083            if (ioctl(mMemInfo[cnt].main_ion_fd,
2084                      ION_IOC_IMPORT, &ion_info_fd) < 0) {
2085                LOGE("ION import failed\n");
2086                for(int i = 0; i < cnt; i++) {
2087                    struct ion_handle_data ion_handle;
2088                    memset(&ion_handle, 0, sizeof(ion_handle));
2089                    ion_handle.handle = mMemInfo[i].handle;
2090                    if (ioctl(mMemInfo[i].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) {
2091                        LOGE("ion free failed");
2092                    }
2093                    close(mMemInfo[i].main_ion_fd);
2094
2095                    if(mLocalFlag[i] != BUFFER_NOT_OWNED) {
2096                        err = mWindow->cancel_buffer(mWindow, mBufferHandle[i]);
2097                        LOGH("cancel_buffer: hdl =%p", (*mBufferHandle[i]));
2098                    }
2099                    mLocalFlag[i] = BUFFER_NOT_OWNED;
2100                    mBufferHandle[i] = NULL;
2101                }
2102                close(mMemInfo[cnt].main_ion_fd);
2103                reset();
2104                ret = UNKNOWN_ERROR;
2105                goto end;
2106            }
2107        }
2108        setMetaData(mPrivateHandle[cnt], UPDATE_COLOR_SPACE, &mColorSpace);
2109        mCameraMemory[cnt] =
2110            mGetMemory(mPrivateHandle[cnt]->fd,
2111                    (size_t)mPrivateHandle[cnt]->size,
2112                    1,
2113                    (void *)this);
2114        LOGH("idx = %d, fd = %d, size = %d, offset = %d",
2115               cnt, mPrivateHandle[cnt]->fd,
2116              mPrivateHandle[cnt]->size,
2117              mPrivateHandle[cnt]->offset);
2118        mMemInfo[cnt].fd = mPrivateHandle[cnt]->fd;
2119        mMemInfo[cnt].size = (size_t)mPrivateHandle[cnt]->size;
2120        mMemInfo[cnt].handle = ion_info_fd.handle;
2121    }
2122
2123    //Cancel min_undequeued_buffer buffers back to the window
2124    for (int i = 0; i < mMinUndequeuedBuffers; i ++) {
2125        err = mWindow->cancel_buffer(mWindow, mBufferHandle[i]);
2126        mLocalFlag[i] = BUFFER_NOT_OWNED;
2127    }
2128
2129end:
2130    if (ret != NO_ERROR) {
2131        mMappableBuffers = 0;
2132    }
2133    LOGD("X ");
2134    ATRACE_END();
2135    return ret;
2136}
2137
2138
2139/*===========================================================================
2140 * FUNCTION   : allocateMore
2141 *
2142 * DESCRIPTION: allocate more requested number of buffers of certain size
2143 *
2144 * PARAMETERS :
2145 *   @count   : number of buffers to be allocated
2146 *   @size    : lenght of the buffer to be allocated
2147 *
2148 * RETURN     : int32_t type of status
2149 *              NO_ERROR  -- success
2150 *              none-zero failure code
2151 *==========================================================================*/
2152int QCameraGrallocMemory::allocateMore(uint8_t /*count*/, size_t /*size*/)
2153{
2154    LOGE("Not implenmented yet");
2155    return UNKNOWN_ERROR;
2156}
2157
2158/*===========================================================================
2159 * FUNCTION   : deallocate
2160 *
2161 * DESCRIPTION: deallocate buffers
2162 *
2163 * PARAMETERS : none
2164 *
2165 * RETURN     : none
2166 *==========================================================================*/
2167void QCameraGrallocMemory::deallocate()
2168{
2169    LOGD("E ", __FUNCTION__);
2170
2171    for (int cnt = 0; cnt < mMappableBuffers; cnt++) {
2172        mCameraMemory[cnt]->release(mCameraMemory[cnt]);
2173        struct ion_handle_data ion_handle;
2174        memset(&ion_handle, 0, sizeof(ion_handle));
2175        ion_handle.handle = mMemInfo[cnt].handle;
2176        if (ioctl(mMemInfo[cnt].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) {
2177            LOGE("ion free failed");
2178        }
2179        close(mMemInfo[cnt].main_ion_fd);
2180        if(mLocalFlag[cnt] != BUFFER_NOT_OWNED) {
2181            if (mWindow) {
2182                mWindow->cancel_buffer(mWindow, mBufferHandle[cnt]);
2183                LOGH("cancel_buffer: hdl =%p", (*mBufferHandle[cnt]));
2184            } else {
2185                LOGE("Preview window is NULL, cannot cancel_buffer: hdl =%p",
2186                      (*mBufferHandle[cnt]));
2187            }
2188        }
2189        mLocalFlag[cnt] = BUFFER_NOT_OWNED;
2190        LOGH("put buffer %d successfully", cnt);
2191    }
2192    mBufferCount = 0;
2193    mMappableBuffers = 0;
2194    LOGD("X ",__FUNCTION__);
2195}
2196
2197/*===========================================================================
2198 * FUNCTION   : cacheOps
2199 *
2200 * DESCRIPTION: ion related memory cache operations
2201 *
2202 * PARAMETERS :
2203 *   @index   : index of the buffer
2204 *   @cmd     : cache ops command
2205 *
2206 * RETURN     : int32_t type of status
2207 *              NO_ERROR  -- success
2208 *              none-zero failure code
2209 *==========================================================================*/
2210int QCameraGrallocMemory::cacheOps(uint32_t index, unsigned int cmd)
2211{
2212    if (index >= mMappableBuffers)
2213        return BAD_INDEX;
2214    return cacheOpsInternal(index, cmd, mCameraMemory[index]->data);
2215}
2216
2217/*===========================================================================
2218 * FUNCTION   : getRegFlags
2219 *
2220 * DESCRIPTION: query initial reg flags
2221 *
2222 * PARAMETERS :
2223 *   @regFlags: initial reg flags of the allocated buffers
2224 *
2225 * RETURN     : int32_t type of status
2226 *              NO_ERROR  -- success
2227 *              none-zero failure code
2228 *==========================================================================*/
2229int QCameraGrallocMemory::getRegFlags(uint8_t *regFlags) const
2230{
2231    int i = 0;
2232    for (i = 0; i < mMinUndequeuedBuffers; i ++)
2233        regFlags[i] = 0;
2234    for (; i < mMappableBuffers; i ++)
2235        regFlags[i] = 1;
2236    for (; i < mBufferCount; i ++)
2237        regFlags[i] = 0;
2238    return NO_ERROR;
2239}
2240
2241/*===========================================================================
2242 * FUNCTION   : getMemory
2243 *
2244 * DESCRIPTION: get camera memory
2245 *
2246 * PARAMETERS :
2247 *   @index   : buffer index
2248 *   @metadata: flag if it's metadata
2249 *
2250 * RETURN     : camera memory ptr
2251 *              NULL if not supported or failed
2252 *==========================================================================*/
2253camera_memory_t *QCameraGrallocMemory::getMemory(uint32_t index,
2254        bool metadata) const
2255{
2256    if (index >= mMappableBuffers || metadata)
2257        return NULL;
2258    return mCameraMemory[index];
2259}
2260
2261/*===========================================================================
2262 * FUNCTION   : getMatchBufIndex
2263 *
2264 * DESCRIPTION: query buffer index by opaque ptr
2265 *
2266 * PARAMETERS :
2267 *   @opaque  : opaque ptr
2268 *   @metadata: flag if it's metadata
2269 *
2270 * RETURN     : buffer index if match found,
2271 *              -1 if failed
2272 *==========================================================================*/
2273int QCameraGrallocMemory::getMatchBufIndex(const void *opaque,
2274                                           bool metadata) const
2275{
2276    int index = -1;
2277    if (metadata) {
2278        return -1;
2279    }
2280    for (int i = 0; i < mMappableBuffers; i++) {
2281        if (mCameraMemory[i]->data == opaque) {
2282            index = i;
2283            break;
2284        }
2285    }
2286    return index;
2287}
2288
2289/*===========================================================================
2290 * FUNCTION   : getPtr
2291 *
2292 * DESCRIPTION: return buffer pointer
2293 *
2294 * PARAMETERS :
2295 *   @index   : index of the buffer
2296 *
2297 * RETURN     : buffer ptr
2298 *==========================================================================*/
2299void *QCameraGrallocMemory::getPtr(uint32_t index) const
2300{
2301    if (index >= mMappableBuffers) {
2302        LOGE("index out of bound");
2303        return (void *)BAD_INDEX;
2304    }
2305    return mCameraMemory[index]->data;
2306}
2307
2308/*===========================================================================
2309 * FUNCTION   : setMappable
2310 *
2311 * DESCRIPTION: configure the number of buffers ready to map
2312 *
2313 * PARAMETERS :
2314 *   @mappable : the number of desired mappable buffers
2315 *
2316 * RETURN     : none
2317 *==========================================================================*/
2318void QCameraGrallocMemory::setMappable(uint8_t mappable)
2319{
2320    if (mMappableBuffers == 0) {
2321        mMappableBuffers = mappable;
2322    }
2323}
2324
2325/*===========================================================================
2326 * FUNCTION   : getMappable
2327 *
2328 * DESCRIPTION: query number of buffers already allocated
2329 *
2330 * PARAMETERS : none
2331 *
2332 * RETURN     : number of buffers already allocated
2333 *==========================================================================*/
2334uint8_t QCameraGrallocMemory::getMappable() const
2335{
2336    return mMappableBuffers;
2337}
2338
2339/*===========================================================================
2340 * FUNCTION   : checkIfAllBuffersMapped
2341 *
2342 * DESCRIPTION: check if all buffers for the are mapped
2343 *
2344 * PARAMETERS : none
2345 *
2346 * RETURN     : 1 if all buffers mapped
2347 *              0 if total buffers not equal to mapped buffers
2348 *==========================================================================*/
2349uint8_t QCameraGrallocMemory::checkIfAllBuffersMapped() const
2350{
2351    LOGH("mBufferCount: %d, mMappableBuffers: %d",
2352             mBufferCount, mMappableBuffers);
2353    return (mBufferCount == mMappableBuffers);
2354}
2355
2356
2357}; //namespace qcamera
2358