1 /*
2  * blur_array.c
3  *
4  *  Created on: 12.02.2018
5  *      Author: thomas
6  */
7 
8 #include <string.h>
9 #include "blur_array.h"
10 
11 /*
12  * initializes an array of blurred buffers
13  */
init_blur_array(BLUR_BUF_ARRAY * arr,int array_length,size_t size,size_t alignement)14 int init_blur_array(BLUR_BUF_ARRAY* arr, int array_length, size_t size, size_t alignement)
15 {
16     // we can't go beyond the max number of threads
17     if (array_length > MAX_NUM_THREADS)
18         return 0;
19 
20     for (int i = 0; i < array_length; i++)
21     {
22         arr->blur_buf_array[i].frame_idx = -1;
23         arr->blur_buf_array[i].blur_buf = aligned_malloc(size, alignement);
24 		arr->blur_buf_array[i].reference_count	= 0;
25         if (arr->blur_buf_array[i].blur_buf == 0)
26             return 0;
27 
28         arr->buffer_size = size;
29         arr->actual_length = i + 1;
30     }
31 
32     pthread_mutex_init(&arr->block, NULL);
33 
34     return 1;
35 }
36 
37 /*
38  * returns the blurred buffer for the frame index or 0 if the frame index was not found
39  */
get_blur_buf(BLUR_BUF_ARRAY * arr,int search_frame_idx)40 float* get_blur_buf(BLUR_BUF_ARRAY* arr, int search_frame_idx)
41 {
42     int array_length = arr->actual_length;
43     BLUR_BUF_STRUCT* s = arr->blur_buf_array;
44 	float *ret = NULL;
45 
46     pthread_mutex_lock(&arr->block);
47 
48     for (int i = 0; i < array_length; i++)
49     {
50 		if (s->frame_idx == search_frame_idx)
51 		{
52 			/* Increment reference counter */
53 			s->reference_count++;
54 
55 			ret = s->blur_buf;
56 			break;
57 		}
58 
59 		// next array item
60 		s++;
61      }
62 
63     pthread_mutex_unlock(&arr->block);
64 
65     return ret;
66 }
67 
68 /*
69  * finds a free slot in the array, assigns the new frame index and copies the buffer
70  */
put_blur_buf(BLUR_BUF_ARRAY * arr,int frame_idx,float * blur_buf)71 int put_blur_buf(BLUR_BUF_ARRAY* arr, int frame_idx, float* blur_buf)
72 {
73     int ret = 0;
74     int array_length = arr->actual_length;
75     size_t buf_size = arr->buffer_size;
76     BLUR_BUF_STRUCT* s = arr->blur_buf_array;
77 
78     pthread_mutex_lock(&arr->block);
79 
80     for (int i = 0; i < array_length; i++)
81     {
82         if (s->frame_idx == -1)
83         {
84             memcpy(s->blur_buf, blur_buf, buf_size);
85             s->frame_idx = frame_idx;
86             ret = 1;
87             break;
88         }
89 
90         // next array item
91         s++;
92     }
93 
94     pthread_mutex_unlock(&arr->block);
95 
96     return ret;
97 }
98 
99 /*
100  * resets the slot in the array to -1 to indicate that the buffer can be used again
101  */
release_blur_buf_slot(BLUR_BUF_ARRAY * arr,int search_frame_idx)102 int release_blur_buf_slot(BLUR_BUF_ARRAY* arr, int search_frame_idx)
103 {
104     int ret = 0;
105     int array_length = arr->actual_length;
106     BLUR_BUF_STRUCT* s = arr->blur_buf_array;
107 
108     pthread_mutex_lock(&arr->block);
109 
110     for (int i = 0; i < array_length; i++)
111     {
112         if (s->frame_idx == search_frame_idx)
113         {
114 			if(s->reference_count <= 0)
115 			{
116 				s->frame_idx = -1;
117 				ret = 1;
118 			}
119 			else
120 			{
121 				ret = -1;
122 			}
123             break;
124         }
125 
126         // next struct
127         s++;
128     }
129 
130     pthread_mutex_unlock(&arr->block);
131 
132     return ret;
133 }
134 
135 /*
136  * gives the memory buffers of the complete array free again
137  */
free_blur_buf(BLUR_BUF_ARRAY * arr)138 void free_blur_buf(BLUR_BUF_ARRAY* arr)
139 {
140     int array_length = arr->actual_length;
141     size_t buf_size = arr->buffer_size;
142     BLUR_BUF_STRUCT* s = arr->blur_buf_array;
143 
144     for (int i = 0; i < array_length; i++)
145     {
146         aligned_free(s->blur_buf);
147 
148         // next struct
149         s++;
150     }
151 
152     pthread_mutex_destroy(&arr->block);
153 }
154 
155 /*
156  * finds a free slot in the array, assigns the new frame index and returns the free buffer pointer
157  * This increases the reference count for this slot
158  */
get_free_blur_buf_slot(BLUR_BUF_ARRAY * arr,int frame_idx)159 float* get_free_blur_buf_slot(BLUR_BUF_ARRAY* arr, int frame_idx)
160 {
161     int array_length = arr->actual_length;
162     BLUR_BUF_STRUCT* s = arr->blur_buf_array;
163 	float *ret = NULL;
164     pthread_mutex_lock(&arr->block);
165 
166     for (int i = 0; i < array_length; i++)
167     {
168         if (s->frame_idx == -1)
169         {
170             s->frame_idx = frame_idx;
171 
172 			/* Increment reference counter */
173 			s->reference_count++;
174 
175 			ret = s->blur_buf;
176 			break;
177         }
178 
179         // next array item
180         s++;
181     }
182     pthread_mutex_unlock(&arr->block);
183 
184     return ret;
185 }
186 
187 /*
188  * Returns the reference counter for the frame index if found, -1 otherwise
189 */
get_blur_buf_reference_count(BLUR_BUF_ARRAY * arr,int frame_idx)190 int get_blur_buf_reference_count(BLUR_BUF_ARRAY* arr, int frame_idx)
191 {
192     int array_length = arr->actual_length;
193     BLUR_BUF_STRUCT* s = arr->blur_buf_array;
194 	int ret = -1;
195 
196     pthread_mutex_lock(&arr->block);
197 
198     for (int i = 0; i < array_length; i++)
199     {
200         if (s->frame_idx == frame_idx)
201         {
202 			ret = s->reference_count;
203 			break;
204         }
205 
206         // next array item
207         s++;
208     }
209 
210     pthread_mutex_unlock(&arr->block);
211 
212     return ret;
213 }
214 
215 /*
216  * releases the reference for the slot in the array which matches the search frame index
217  */
release_blur_buf_reference(BLUR_BUF_ARRAY * arr,int search_frame_idx)218 int release_blur_buf_reference(BLUR_BUF_ARRAY* arr, int search_frame_idx)
219 {
220     int ret = -1;
221     int array_length = arr->actual_length;
222     BLUR_BUF_STRUCT* s = arr->blur_buf_array;
223 
224     pthread_mutex_lock(&arr->block);
225 
226     for (int i = 0; i < array_length; i++)
227     {
228         if (s->frame_idx == search_frame_idx)
229         {
230 			s->reference_count--;
231 			ret = 0;
232 			break;
233 		}
234 
235         // next struct
236         s++;
237     }
238 
239     pthread_mutex_unlock(&arr->block);
240 
241     return ret;
242 }
243