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