blob: f52bb05c42ae63e6bf9fd3af8bb6df3ae0b0adb9
1 | /* |
2 | * Copyright (C) 2011 The Android Open Source Project |
3 | * |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | * you may not use this file except in compliance with the License. |
6 | * You may obtain a copy of the License at |
7 | * |
8 | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | * |
10 | * Unless required by applicable law or agreed to in writing, software |
11 | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. |
15 | */ |
16 | |
17 | #define LOG_TAG "CAMHAL_MemoryManager " |
18 | |
19 | #include "CameraHal.h" |
20 | #include "ExCameraParameters.h" |
21 | |
22 | namespace android { |
23 | /*--------------------MemoryManager Class STARTS here-----------------------------*/ |
24 | int MemoryManager::setRequestMemoryCallback(camera_request_memory get_memory) |
25 | { |
26 | mRequestMemory = get_memory; |
27 | return 0; |
28 | } |
29 | |
30 | void* MemoryManager::allocateBuffer(int width, int height, const char* format, int &bytes, int numBufs) |
31 | { |
32 | LOG_FUNCTION_NAME; |
33 | ///We allocate numBufs+1 because the last entry will be marked NULL to indicate |
34 | ///end of array, which is used when freeing the buffers |
35 | const uint numArrayEntriesC = (uint)(numBufs+1); |
36 | |
37 | if (!mRequestMemory) |
38 | { |
39 | CAMHAL_LOGEA("no req. mem cb"); |
40 | LOG_FUNCTION_NAME_EXIT; |
41 | return NULL; |
42 | } |
43 | |
44 | ///Allocate a buffer array |
45 | uint32_t *bufsArr = new uint32_t [numArrayEntriesC]; |
46 | if(!bufsArr) |
47 | { |
48 | CAMHAL_LOGEB("Allocation failed when creating buffers array of %d uint32_t elements", numArrayEntriesC); |
49 | LOG_FUNCTION_NAME_EXIT; |
50 | return NULL; |
51 | } |
52 | |
53 | ///Initialize the array with zeros - this will help us while freeing the array in case of error |
54 | ///If a value of an array element is NULL, it means we didnt allocate it |
55 | memset(bufsArr, 0, sizeof(*bufsArr) * numArrayEntriesC); |
56 | |
57 | //2D Allocations are not supported currently |
58 | if(bytes != 0) |
59 | { |
60 | camera_memory_t* handle = NULL; |
61 | |
62 | ///1D buffers |
63 | for (int i = 0; i < numBufs; i++) |
64 | { |
65 | handle = mRequestMemory(-1, bytes, 1, NULL); |
66 | if(!handle) |
67 | { |
68 | CAMHAL_LOGEA("req. mem failed"); |
69 | goto error; |
70 | } |
71 | |
72 | CAMHAL_LOGDB("handle = %x, nSize = %d", (uint32_t)handle, bytes); |
73 | bufsArr[i] = (uint32_t)handle; |
74 | |
75 | mMemoryHandleMap.add(bufsArr[i], (unsigned int)handle); |
76 | } |
77 | } |
78 | |
79 | LOG_FUNCTION_NAME_EXIT; |
80 | |
81 | return (void*)bufsArr; |
82 | |
83 | error: |
84 | CAMHAL_LOGEA("Freeing buffers already allocated after error occurred"); |
85 | freeBuffer(bufsArr); |
86 | |
87 | if ( NULL != mErrorNotifier.get() ) |
88 | { |
89 | mErrorNotifier->errorNotify(-ENOMEM); |
90 | } |
91 | |
92 | LOG_FUNCTION_NAME_EXIT; |
93 | return NULL; |
94 | } |
95 | |
96 | uint32_t * MemoryManager::getOffsets() |
97 | { |
98 | LOG_FUNCTION_NAME; |
99 | LOG_FUNCTION_NAME_EXIT; |
100 | return NULL; |
101 | } |
102 | |
103 | int MemoryManager::getFd() |
104 | { |
105 | LOG_FUNCTION_NAME; |
106 | LOG_FUNCTION_NAME_EXIT; |
107 | return -1; |
108 | } |
109 | |
110 | int MemoryManager::freeBuffer(void* buf) |
111 | { |
112 | status_t ret = NO_ERROR; |
113 | LOG_FUNCTION_NAME; |
114 | |
115 | uint32_t *bufEntry = (uint32_t*)buf; |
116 | |
117 | if(!bufEntry) |
118 | { |
119 | CAMHAL_LOGEA("NULL pointer passed to freebuffer"); |
120 | LOG_FUNCTION_NAME_EXIT; |
121 | return BAD_VALUE; |
122 | } |
123 | |
124 | while(*bufEntry) |
125 | { |
126 | unsigned int ptr = (unsigned int) *bufEntry++; |
127 | camera_memory_t* handle = (camera_memory_t*)mMemoryHandleMap.valueFor(ptr); |
128 | if(handle) |
129 | { |
130 | handle->release(handle); |
131 | } |
132 | else |
133 | { |
134 | CAMHAL_LOGEA("Not a valid Memory Manager buffer"); |
135 | } |
136 | } |
137 | |
138 | ///@todo Check if this way of deleting array is correct, else use malloc/free |
139 | uint32_t * bufArr = (uint32_t*)buf; |
140 | delete [] bufArr; |
141 | |
142 | LOG_FUNCTION_NAME_EXIT; |
143 | return ret; |
144 | } |
145 | |
146 | status_t MemoryManager::setErrorHandler(ErrorNotifier *errorNotifier) |
147 | { |
148 | status_t ret = NO_ERROR; |
149 | |
150 | LOG_FUNCTION_NAME; |
151 | |
152 | if ( NULL == errorNotifier ) |
153 | { |
154 | CAMHAL_LOGEA("Invalid Error Notifier reference"); |
155 | ret = -EINVAL; |
156 | } |
157 | |
158 | if ( NO_ERROR == ret ) |
159 | { |
160 | mErrorNotifier = errorNotifier; |
161 | } |
162 | |
163 | LOG_FUNCTION_NAME_EXIT; |
164 | |
165 | return ret; |
166 | } |
167 | |
168 | }; |
169 | |
170 | |
171 | /*--------------------MemoryManager Class ENDS here-----------------------------*/ |
172 |