1 /*
2 * Copyright(c) 2019 Intel Corporation
3 * SPDX - License - Identifier: BSD - 2 - Clause - Patent
4 */
5
6 #include <stdlib.h>
7
8 #include "EbSystemResourceManager.h"
9
10 /**************************************
11 * eb_fifo_ctor
12 **************************************/
eb_fifo_ctor(EbFifo * fifo_ptr,uint32_t initial_count,uint32_t max_count,EbObjectWrapper * first_wrapper_ptr,EbObjectWrapper * last_wrapper_ptr,EbMuxingQueue * queue_ptr)13 static EbErrorType eb_fifo_ctor(
14 EbFifo *fifo_ptr,
15 uint32_t initial_count,
16 uint32_t max_count,
17 EbObjectWrapper *first_wrapper_ptr,
18 EbObjectWrapper *last_wrapper_ptr,
19 EbMuxingQueue *queue_ptr)
20 {
21 // Create Counting Semaphore
22 EB_CREATESEMAPHORE(EbHandle, fifo_ptr->counting_semaphore, sizeof(EbHandle), EB_SEMAPHORE, initial_count, max_count);
23
24 // Create Buffer Pool Mutex
25 EB_CREATEMUTEX(EbHandle, fifo_ptr->lockout_mutex, sizeof(EbHandle), EB_MUTEX);
26
27 // Initialize Fifo First & Last ptrs
28 fifo_ptr->first_ptr = first_wrapper_ptr;
29 fifo_ptr->last_ptr = last_wrapper_ptr;
30
31 // Copy the Muxing Queue ptr this Fifo belongs to
32 fifo_ptr->queue_ptr = queue_ptr;
33
34 return EB_ErrorNone;
35 }
36
37 /**************************************
38 * eb_fifo_push_back
39 **************************************/
eb_fifo_push_back(EbFifo * fifo_ptr,EbObjectWrapper * wrapper_ptr)40 static EbErrorType eb_fifo_push_back(
41 EbFifo *fifo_ptr,
42 EbObjectWrapper *wrapper_ptr)
43 {
44 EbErrorType return_error = EB_ErrorNone;
45
46 // If FIFO is empty
47 if(fifo_ptr->first_ptr == (EbObjectWrapper*) EB_NULL) {
48 fifo_ptr->first_ptr = wrapper_ptr;
49 fifo_ptr->last_ptr = wrapper_ptr;
50 } else {
51 fifo_ptr->last_ptr->next_ptr = wrapper_ptr;
52 fifo_ptr->last_ptr = wrapper_ptr;
53 }
54
55 fifo_ptr->last_ptr->next_ptr = (EbObjectWrapper*) EB_NULL;
56
57 return return_error;
58 }
59
60 /**************************************
61 * eb_fifo_pop_front
62 **************************************/
eb_fifo_pop_front(EbFifo * fifo_ptr,EbObjectWrapper ** wrapper_ptr)63 static EbErrorType eb_fifo_pop_front(
64 EbFifo *fifo_ptr,
65 EbObjectWrapper **wrapper_ptr)
66 {
67 EbErrorType return_error = EB_ErrorNone;
68
69 // Set wrapper_ptr to head of BufferPool
70 *wrapper_ptr = fifo_ptr->first_ptr;
71
72 // Update tail of BufferPool if the BufferPool is now empty
73 fifo_ptr->last_ptr = (fifo_ptr->first_ptr == fifo_ptr->last_ptr) ? (EbObjectWrapper*) EB_NULL: fifo_ptr->last_ptr;
74
75 // Update head of BufferPool
76 fifo_ptr->first_ptr = fifo_ptr->first_ptr->next_ptr;
77
78 return return_error;
79 }
80
81 /**************************************
82 * eb_circular_buffer_ctor
83 **************************************/
eb_circular_buffer_ctor(EbCircularBuffer ** buffer_dbl_ptr,uint32_t buffer_total_count)84 static EbErrorType eb_circular_buffer_ctor(
85 EbCircularBuffer **buffer_dbl_ptr,
86 uint32_t buffer_total_count)
87 {
88 uint32_t buffer_index;
89 EbCircularBuffer *buffer_ptr;
90
91 EB_MALLOC(EbCircularBuffer*, buffer_ptr, sizeof(EbCircularBuffer), EB_N_PTR);
92
93 *buffer_dbl_ptr = buffer_ptr;
94
95 buffer_ptr->buffer_total_count = buffer_total_count;
96
97 EB_MALLOC(EbPtr *, buffer_ptr->array_ptr, sizeof(EbPtr) * buffer_ptr->buffer_total_count, EB_N_PTR);
98
99 for(buffer_index=0; buffer_index < buffer_ptr->buffer_total_count; ++buffer_index) {
100 buffer_ptr->array_ptr[buffer_index] = EB_NULL;
101 }
102
103 buffer_ptr->head_index = 0;
104 buffer_ptr->tail_index = 0;
105
106 buffer_ptr->current_count = 0;
107
108 return EB_ErrorNone;
109 }
110
111 /**************************************
112 * eb_circular_buffer_empty_check
113 **************************************/
eb_circular_buffer_empty_check(EbCircularBuffer * buffer_ptr)114 static EB_BOOL eb_circular_buffer_empty_check(
115 EbCircularBuffer *buffer_ptr)
116 {
117 return ((buffer_ptr->head_index == buffer_ptr->tail_index) && (buffer_ptr->array_ptr[buffer_ptr->head_index] == EB_NULL)) ? EB_TRUE : EB_FALSE;
118 }
119
120 /**************************************
121 * eb_circular_buffer_pop_front
122 **************************************/
eb_circular_buffer_pop_front(EbCircularBuffer * buffer_ptr,EbPtr * object_ptr)123 static EbErrorType eb_circular_buffer_pop_front(
124 EbCircularBuffer *buffer_ptr,
125 EbPtr *object_ptr)
126 {
127 EbErrorType return_error = EB_ErrorNone;
128
129 // Copy the head of the buffer into the object_ptr
130 *object_ptr = buffer_ptr->array_ptr[buffer_ptr->head_index];
131 buffer_ptr->array_ptr[buffer_ptr->head_index] = EB_NULL;
132
133 // Increment the head & check for rollover
134 buffer_ptr->head_index = (buffer_ptr->head_index == buffer_ptr->buffer_total_count - 1) ? 0 : buffer_ptr->head_index + 1;
135
136 // Decrement the Current Count
137 --buffer_ptr->current_count;
138
139 return return_error;
140 }
141
142 /**************************************
143 * eb_circular_buffer_push_back
144 **************************************/
eb_circular_buffer_push_back(EbCircularBuffer * buffer_ptr,EbPtr object_ptr)145 static EbErrorType eb_circular_buffer_push_back(
146 EbCircularBuffer *buffer_ptr,
147 EbPtr object_ptr)
148 {
149 EbErrorType return_error = EB_ErrorNone;
150
151 // Copy the pointer into the array
152 buffer_ptr->array_ptr[buffer_ptr->tail_index] = object_ptr;
153
154 // Increment the tail & check for rollover
155 buffer_ptr->tail_index = (buffer_ptr->tail_index == buffer_ptr->buffer_total_count - 1) ? 0 : buffer_ptr->tail_index + 1;
156
157 // Increment the Current Count
158 ++buffer_ptr->current_count;
159
160 return return_error;
161 }
162
163 /**************************************
164 * eb_circular_buffer_push_front
165 **************************************/
eb_circular_buffer_push_front(EbCircularBuffer * buffer_ptr,EbPtr object_ptr)166 static EbErrorType eb_circular_buffer_push_front(
167 EbCircularBuffer *buffer_ptr,
168 EbPtr object_ptr)
169 {
170 EbErrorType return_error = EB_ErrorNone;
171
172 // Decrement the head_index
173 buffer_ptr->head_index = (buffer_ptr->head_index == 0) ? buffer_ptr->buffer_total_count - 1 : buffer_ptr->head_index - 1;
174
175 // Copy the pointer into the array
176 buffer_ptr->array_ptr[buffer_ptr->head_index] = object_ptr;
177
178 // Increment the Current Count
179 ++buffer_ptr->current_count;
180
181 return return_error;
182 }
183
184 /**************************************
185 * eb_muxing_queue_ctor
186 **************************************/
eb_muxing_queue_ctor(EbMuxingQueue ** queue_dbl_ptr,uint32_t object_total_count,uint32_t process_total_count,EbFifo *** process_fifo_ptr_array_ptr)187 static EbErrorType eb_muxing_queue_ctor(
188 EbMuxingQueue **queue_dbl_ptr,
189 uint32_t object_total_count,
190 uint32_t process_total_count,
191 EbFifo ***process_fifo_ptr_array_ptr)
192 {
193 EbMuxingQueue *queue_ptr;
194 uint32_t process_index;
195 EbErrorType return_error = EB_ErrorNone;
196
197 EB_MALLOC(EbMuxingQueue *, queue_ptr, sizeof(EbMuxingQueue), EB_N_PTR);
198 *queue_dbl_ptr = queue_ptr;
199
200 queue_ptr->process_total_count = process_total_count;
201
202 // Lockout Mutex
203 EB_CREATEMUTEX(EbHandle, queue_ptr->lockout_mutex, sizeof(EbHandle), EB_MUTEX);
204
205 // Construct Object Circular Buffer
206 return_error = eb_circular_buffer_ctor(
207 &queue_ptr->object_queue,
208 object_total_count);
209 if (return_error == EB_ErrorInsufficientResources){
210 return EB_ErrorInsufficientResources;
211 }
212 // Construct Process Circular Buffer
213 return_error = eb_circular_buffer_ctor(
214 &queue_ptr->process_queue,
215 queue_ptr->process_total_count);
216 if (return_error == EB_ErrorInsufficientResources){
217 return EB_ErrorInsufficientResources;
218 }
219 // Construct the Process Fifos
220 EB_MALLOC(EbFifo**, queue_ptr->process_fifo_ptr_array, sizeof(EbFifo*) * queue_ptr->process_total_count, EB_N_PTR);
221
222 for(process_index=0; process_index < queue_ptr->process_total_count; ++process_index) {
223 EB_MALLOC(EbFifo*, queue_ptr->process_fifo_ptr_array[process_index], sizeof(EbFifo) * queue_ptr->process_total_count, EB_N_PTR);
224 return_error = eb_fifo_ctor(
225 queue_ptr->process_fifo_ptr_array[process_index],
226 0,
227 object_total_count,
228 (EbObjectWrapper *)EB_NULL,
229 (EbObjectWrapper *)EB_NULL,
230 queue_ptr);
231 if (return_error == EB_ErrorInsufficientResources){
232 return EB_ErrorInsufficientResources;
233 }
234 }
235
236 *process_fifo_ptr_array_ptr = queue_ptr->process_fifo_ptr_array;
237
238 return return_error;
239 }
240
241 /**************************************
242 * eb_muxing_queue_assignation
243 **************************************/
eb_muxing_queue_assignation(EbMuxingQueue * queue_ptr)244 static EbErrorType eb_muxing_queue_assignation(
245 EbMuxingQueue *queue_ptr)
246 {
247 EbErrorType return_error = EB_ErrorNone;
248 EbFifo *process_fifo_ptr;
249 EbObjectWrapper *wrapper_ptr;
250
251 // while loop
252 while((eb_circular_buffer_empty_check(queue_ptr->object_queue) == EB_FALSE) &&
253 (eb_circular_buffer_empty_check(queue_ptr->process_queue) == EB_FALSE)) {
254 // Get the next process
255 eb_circular_buffer_pop_front(
256 queue_ptr->process_queue,
257 (void **) &process_fifo_ptr);
258
259 // Get the next object
260 eb_circular_buffer_pop_front(
261 queue_ptr->object_queue,
262 (void **) &wrapper_ptr);
263
264 // Block on the Process Fifo's Mutex
265 eb_vp9_block_on_mutex(process_fifo_ptr->lockout_mutex);
266
267 // Put the object on the fifo
268 eb_fifo_push_back(
269 process_fifo_ptr,
270 wrapper_ptr);
271
272 // Release the Process Fifo's Mutex
273 eb_vp9_release_mutex(process_fifo_ptr->lockout_mutex);
274
275 // Post the semaphore
276 eb_vp9_post_semaphore(process_fifo_ptr->counting_semaphore);
277 }
278
279 return return_error;
280 }
281
282 /**************************************
283 * eb_muxing_queue_object_push_back
284 **************************************/
eb_muxing_queue_object_push_back(EbMuxingQueue * queue_ptr,EbObjectWrapper * object_ptr)285 static EbErrorType eb_muxing_queue_object_push_back(
286 EbMuxingQueue *queue_ptr,
287 EbObjectWrapper *object_ptr)
288 {
289 EbErrorType return_error = EB_ErrorNone;
290
291 eb_circular_buffer_push_back(
292 queue_ptr->object_queue,
293 object_ptr);
294
295 eb_muxing_queue_assignation(queue_ptr);
296
297 return return_error;
298 }
299
300 /**************************************
301 * eb_muxing_queue_object_push_front
302 **************************************/
eb_muxing_queue_object_push_front(EbMuxingQueue * queue_ptr,EbObjectWrapper * object_ptr)303 static EbErrorType eb_muxing_queue_object_push_front(
304 EbMuxingQueue *queue_ptr,
305 EbObjectWrapper *object_ptr)
306 {
307 EbErrorType return_error = EB_ErrorNone;
308
309 eb_circular_buffer_push_front(
310 queue_ptr->object_queue,
311 object_ptr);
312
313 eb_muxing_queue_assignation(queue_ptr);
314
315 return return_error;
316 }
317
318 /*********************************************************************
319 * eb_vp9_object_release_enable
320 * Enables the release_enable member of EbObjectWrapper. Used by
321 * certain objects (e.g. SequenceControlSet) to control whether
322 * EbObjectWrappers are allowed to be released or not.
323 *
324 * resource_ptr
325 * pointer to the SystemResource that manages the EbObjectWrapper.
326 * The emptyFifo's lockout_mutex is used to write protect the
327 * modification of the EbObjectWrapper.
328 *
329 * wrapper_ptr
330 * pointer to the EbObjectWrapper to be modified.
331 *********************************************************************/
eb_vp9_object_release_enable(EbObjectWrapper * wrapper_ptr)332 EbErrorType eb_vp9_object_release_enable(
333 EbObjectWrapper *wrapper_ptr)
334 {
335 EbErrorType return_error = EB_ErrorNone;
336
337 eb_vp9_block_on_mutex(wrapper_ptr->system_resource_ptr->empty_queue->lockout_mutex);
338
339 wrapper_ptr->release_enable = EB_TRUE;
340
341 eb_vp9_release_mutex(wrapper_ptr->system_resource_ptr->empty_queue->lockout_mutex);
342
343 return return_error;
344 }
345
346 /*********************************************************************
347 * eb_vp9_object_release_disable
348 * Disables the release_enable member of EbObjectWrapper. Used by
349 * certain objects (e.g. SequenceControlSet) to control whether
350 * EbObjectWrappers are allowed to be released or not.
351 *
352 * resource_ptr
353 * pointer to the SystemResource that manages the EbObjectWrapper.
354 * The emptyFifo's lockout_mutex is used to write protect the
355 * modification of the EbObjectWrapper.
356 *
357 * wrapper_ptr
358 * pointer to the EbObjectWrapper to be modified.
359 *********************************************************************/
eb_vp9_object_release_disable(EbObjectWrapper * wrapper_ptr)360 EbErrorType eb_vp9_object_release_disable(
361 EbObjectWrapper *wrapper_ptr)
362 {
363 EbErrorType return_error = EB_ErrorNone;
364
365 eb_vp9_block_on_mutex(wrapper_ptr->system_resource_ptr->empty_queue->lockout_mutex);
366
367 wrapper_ptr->release_enable = EB_FALSE;
368
369 eb_vp9_release_mutex(wrapper_ptr->system_resource_ptr->empty_queue->lockout_mutex);
370
371 return return_error;
372 }
373
374 /*********************************************************************
375 * eb_vp9_object_inc_live_count
376 * Increments the live_count member of EbObjectWrapper. Used by
377 * certain objects (e.g. SequenceControlSet) to count the number of active
378 * pointers of a EbObjectWrapper in pipeline at any point in time.
379 *
380 * resource_ptr
381 * pointer to the SystemResource that manages the EbObjectWrapper.
382 * The emptyFifo's lockout_mutex is used to write protect the
383 * modification of the EbObjectWrapper.
384 *
385 * wrapper_ptr
386 * pointer to the EbObjectWrapper to be modified.
387 *********************************************************************/
eb_vp9_object_inc_live_count(EbObjectWrapper * wrapper_ptr,uint32_t increment_number)388 EbErrorType eb_vp9_object_inc_live_count(
389 EbObjectWrapper *wrapper_ptr,
390 uint32_t increment_number)
391 {
392 EbErrorType return_error = EB_ErrorNone;
393
394 eb_vp9_block_on_mutex(wrapper_ptr->system_resource_ptr->empty_queue->lockout_mutex);
395
396 wrapper_ptr->live_count += increment_number;
397
398 eb_vp9_release_mutex(wrapper_ptr->system_resource_ptr->empty_queue->lockout_mutex);
399
400 return return_error;
401 }
402
403 /*********************************************************************
404 * eb_vp9_system_resource_ctor
405 * Constructor for EbSystemResource. Fully constructs all members
406 * of EbSystemResource including the object with the passed
407 * object_ctor function.
408 *
409 * resource_ptr
410 * pointer that will contain the SystemResource to be constructed.
411 *
412 * object_total_count
413 * Number of objects to be managed by the SystemResource.
414 *
415 * full_fifo_enabled
416 * Bool that describes if the SystemResource is to have an output
417 * fifo. An outputFifo is not used by certain objects (e.g.
418 * SequenceControlSet).
419 *
420 * object_ctor
421 * Function pointer to the constructor of the object managed by
422 * SystemResource referenced by resource_ptr. No object level
423 * construction is performed if object_ctor is NULL.
424 *
425 * object_init_data_ptr
426
427 * pointer to data block to be used during the construction of
428 * the object. object_init_data_ptr is passed to object_ctor when
429 * object_ctor is called.
430 *********************************************************************/
eb_vp9_system_resource_ctor(EbSystemResource ** resource_dbl_ptr,uint32_t object_total_count,uint32_t producer_process_total_count,uint32_t consumer_process_total_count,EbFifo *** producer_fifo_ptr_array_ptr,EbFifo *** consumer_fifo_ptr_array_ptr,EB_BOOL full_fifo_enabled,EB_CTOR object_ctor,EbPtr object_init_data_ptr)431 EbErrorType eb_vp9_system_resource_ctor(
432 EbSystemResource **resource_dbl_ptr,
433 uint32_t object_total_count,
434 uint32_t producer_process_total_count,
435 uint32_t consumer_process_total_count,
436 EbFifo ***producer_fifo_ptr_array_ptr,
437 EbFifo ***consumer_fifo_ptr_array_ptr,
438 EB_BOOL full_fifo_enabled,
439 EB_CTOR object_ctor,
440 EbPtr object_init_data_ptr)
441 {
442 uint32_t wrapperIndex;
443 EbErrorType return_error = EB_ErrorNone;
444 // Allocate the System Resource
445 EbSystemResource *resource_ptr;
446
447 EB_MALLOC(EbSystemResource*, resource_ptr, sizeof(EbSystemResource), EB_N_PTR);
448 *resource_dbl_ptr = resource_ptr;
449
450 resource_ptr->object_total_count = object_total_count;
451
452 // Allocate array for wrapper pointers
453 EB_MALLOC(EbObjectWrapper**, resource_ptr->wrapper_ptr_pool, sizeof(EbObjectWrapper*) * resource_ptr->object_total_count, EB_N_PTR);
454
455 // Initialize each wrapper
456 for (wrapperIndex=0; wrapperIndex < resource_ptr->object_total_count; ++wrapperIndex) {
457 EB_MALLOC(EbObjectWrapper*, resource_ptr->wrapper_ptr_pool[wrapperIndex], sizeof(EbObjectWrapper), EB_N_PTR);
458 resource_ptr->wrapper_ptr_pool[wrapperIndex]->live_count = 0;
459 resource_ptr->wrapper_ptr_pool[wrapperIndex]->release_enable = EB_TRUE;
460 resource_ptr->wrapper_ptr_pool[wrapperIndex]->system_resource_ptr = resource_ptr;
461
462 // Call the Constructor for each element
463 if(object_ctor) {
464 return_error = object_ctor(
465 &resource_ptr->wrapper_ptr_pool[wrapperIndex]->object_ptr,
466 object_init_data_ptr);
467 if (return_error == EB_ErrorInsufficientResources){
468 return EB_ErrorInsufficientResources;
469 }
470 }
471 }
472
473 // Initialize the Empty Queue
474 return_error = eb_muxing_queue_ctor(
475 &resource_ptr->empty_queue,
476 resource_ptr->object_total_count,
477 producer_process_total_count,
478 producer_fifo_ptr_array_ptr);
479 if (return_error == EB_ErrorInsufficientResources){
480 return EB_ErrorInsufficientResources;
481 }
482 // Fill the Empty Fifo with every ObjectWrapper
483 for (wrapperIndex=0; wrapperIndex < resource_ptr->object_total_count; ++wrapperIndex) {
484 eb_muxing_queue_object_push_back(
485 resource_ptr->empty_queue,
486 resource_ptr->wrapper_ptr_pool[wrapperIndex]);
487 }
488
489 // Initialize the Full Queue
490 if (full_fifo_enabled == EB_TRUE) {
491 return_error = eb_muxing_queue_ctor(
492 &resource_ptr->full_queue,
493 resource_ptr->object_total_count,
494 consumer_process_total_count,
495 consumer_fifo_ptr_array_ptr);
496 if (return_error == EB_ErrorInsufficientResources){
497 return EB_ErrorInsufficientResources;
498 }
499 } else {
500 resource_ptr->full_queue = (EbMuxingQueue *)EB_NULL;
501 consumer_fifo_ptr_array_ptr = (EbFifo ***)EB_NULL;
502 }
503
504 return return_error;
505 }
506
507 /*********************************************************************
508 * EbSystemResourceReleaseProcess
509 *********************************************************************/
eb_release_process(EbFifo * process_fifo_ptr)510 static EbErrorType eb_release_process(
511 EbFifo *process_fifo_ptr)
512 {
513 EbErrorType return_error = EB_ErrorNone;
514
515 eb_vp9_block_on_mutex(process_fifo_ptr->queue_ptr->lockout_mutex);
516
517 eb_circular_buffer_push_front(
518 process_fifo_ptr->queue_ptr->process_queue,
519 process_fifo_ptr);
520
521 eb_muxing_queue_assignation(process_fifo_ptr->queue_ptr);
522
523 eb_vp9_release_mutex(process_fifo_ptr->queue_ptr->lockout_mutex);
524
525 return return_error;
526 }
527
528 /*********************************************************************
529 * EbSystemResourcePostObject
530 * Queues a full EbObjectWrapper to the SystemResource. This
531 * function posts the SystemResource fullFifo counting_semaphore.
532 * This function is write protected by the SystemResource fullFifo
533 * lockout_mutex.
534 *
535 * resource_ptr
536 * pointer to the SystemResource that the EbObjectWrapper is
537 * posted to.
538 *
539 * wrapper_ptr
540 * pointer to EbObjectWrapper to be posted.
541 *********************************************************************/
eb_vp9_post_full_object(EbObjectWrapper * object_ptr)542 EbErrorType eb_vp9_post_full_object(
543 EbObjectWrapper *object_ptr)
544 {
545 EbErrorType return_error = EB_ErrorNone;
546
547 eb_vp9_block_on_mutex(object_ptr->system_resource_ptr->full_queue->lockout_mutex);
548
549 eb_muxing_queue_object_push_back(
550 object_ptr->system_resource_ptr->full_queue,
551 object_ptr);
552
553 eb_vp9_release_mutex(object_ptr->system_resource_ptr->full_queue->lockout_mutex);
554
555 return return_error;
556 }
557
558 /*********************************************************************
559 * EbSystemResourceReleaseObject
560 * Queues an empty EbObjectWrapper to the SystemResource. This
561 * function posts the SystemResource emptyFifo counting_semaphore.
562 * This function is write protected by the SystemResource emptyFifo
563 * lockout_mutex.
564 *
565 * object_ptr
566 * pointer to EbObjectWrapper to be released.
567 *********************************************************************/
eb_vp9_release_object(EbObjectWrapper * object_ptr)568 EbErrorType eb_vp9_release_object(
569 EbObjectWrapper *object_ptr)
570 {
571 EbErrorType return_error = EB_ErrorNone;
572
573 eb_vp9_block_on_mutex(object_ptr->system_resource_ptr->empty_queue->lockout_mutex);
574
575 // Decrement live_count
576 object_ptr->live_count = (object_ptr->live_count == 0) ? object_ptr->live_count : object_ptr->live_count - 1;
577
578 if((object_ptr->release_enable == EB_TRUE) && (object_ptr->live_count == 0)) {
579
580 // Set live_count to EB_ObjectWrapperReleasedValue
581 object_ptr->live_count = EB_ObjectWrapperReleasedValue;
582
583 eb_muxing_queue_object_push_front(
584 object_ptr->system_resource_ptr->empty_queue,
585 object_ptr);
586
587 }
588
589 eb_vp9_release_mutex(object_ptr->system_resource_ptr->empty_queue->lockout_mutex);
590
591 return return_error;
592 }
593
594 /*********************************************************************
595 * EbSystemResourceGetEmptyObject
596 * Dequeues an empty EbObjectWrapper from the SystemResource. This
597 * function blocks on the SystemResource emptyFifo counting_semaphore.
598 * This function is write protected by the SystemResource emptyFifo
599 * lockout_mutex.
600 *
601 * resource_ptr
602 * pointer to the SystemResource that provides the empty
603 * EbObjectWrapper.
604 *
605 * wrapper_dbl_ptr
606 * Double pointer used to pass the pointer to the empty
607 * EbObjectWrapper pointer.
608 *********************************************************************/
eb_vp9_get_empty_object(EbFifo * empty_fifo_ptr,EbObjectWrapper ** wrapper_dbl_ptr)609 EbErrorType eb_vp9_get_empty_object(
610 EbFifo *empty_fifo_ptr,
611 EbObjectWrapper **wrapper_dbl_ptr)
612 {
613 EbErrorType return_error = EB_ErrorNone;
614
615 // Queue the Fifo requesting the empty fifo
616 eb_release_process(empty_fifo_ptr);
617
618 // Block on the counting Semaphore until an empty buffer is available
619 eb_vp9_block_on_semaphore(empty_fifo_ptr->counting_semaphore);
620
621 // Acquire lockout Mutex
622 eb_vp9_block_on_mutex(empty_fifo_ptr->lockout_mutex);
623
624 // Get the empty object
625 eb_fifo_pop_front(
626 empty_fifo_ptr,
627 wrapper_dbl_ptr);
628
629 // Reset the wrapper's live_count
630 (*wrapper_dbl_ptr)->live_count = 0;
631
632 // Object release enable
633 (*wrapper_dbl_ptr)->release_enable = EB_TRUE;
634
635 // Release Mutex
636 eb_vp9_release_mutex(empty_fifo_ptr->lockout_mutex);
637
638 return return_error;
639 }
640
641 /*********************************************************************
642 * EbSystemResourceGetFullObject
643 * Dequeues an full EbObjectWrapper from the SystemResource. This
644 * function blocks on the SystemResource fullFifo counting_semaphore.
645 * This function is write protected by the SystemResource fullFifo
646 * lockout_mutex.
647 *
648 * resource_ptr
649 * pointer to the SystemResource that provides the full
650 * EbObjectWrapper.
651 *
652 * wrapper_dbl_ptr
653 * Double pointer used to pass the pointer to the full
654 * EbObjectWrapper pointer.
655 *********************************************************************/
eb_vp9_get_full_object(EbFifo * full_fifo_ptr,EbObjectWrapper ** wrapper_dbl_ptr)656 EbErrorType eb_vp9_get_full_object(
657 EbFifo *full_fifo_ptr,
658 EbObjectWrapper **wrapper_dbl_ptr)
659 {
660 EbErrorType return_error = EB_ErrorNone;
661
662 // Queue the Fifo requesting the full fifo
663 eb_release_process(full_fifo_ptr);
664
665 // Block on the counting Semaphore until an empty buffer is available
666 eb_vp9_block_on_semaphore(full_fifo_ptr->counting_semaphore);
667
668 // Acquire lockout Mutex
669 eb_vp9_block_on_mutex(full_fifo_ptr->lockout_mutex);
670
671 eb_fifo_pop_front(
672 full_fifo_ptr,
673 wrapper_dbl_ptr);
674
675 // Release Mutex
676 eb_vp9_release_mutex(full_fifo_ptr->lockout_mutex);
677
678 return return_error;
679 }
680 /**************************************
681 * EbFifoPopFront
682 **************************************/
eb_fifo_peak_front(EbFifo * fifo_ptr)683 static EB_BOOL eb_fifo_peak_front(
684 EbFifo *fifo_ptr){
685
686 // Set wrapper_ptr to head of BufferPool
687 if (fifo_ptr->first_ptr == (EbObjectWrapper*)EB_NULL)
688 return EB_TRUE;
689 else
690 return EB_FALSE;
691 }
692
eb_vp9_get_full_object_non_blocking(EbFifo * full_fifo_ptr,EbObjectWrapper ** wrapper_dbl_ptr)693 EbErrorType eb_vp9_get_full_object_non_blocking(
694 EbFifo *full_fifo_ptr,
695 EbObjectWrapper **wrapper_dbl_ptr){
696
697 EbErrorType return_error = EB_ErrorNone;
698 EB_BOOL fifo_empty;
699 // Queue the Fifo requesting the full fifo
700 eb_release_process(full_fifo_ptr);
701
702 // Acquire lockout Mutex
703 eb_vp9_block_on_mutex(full_fifo_ptr->lockout_mutex);
704
705 fifo_empty = eb_fifo_peak_front(
706 full_fifo_ptr);
707
708 // Release Mutex
709 eb_vp9_release_mutex(full_fifo_ptr->lockout_mutex);
710
711 if (fifo_empty == EB_FALSE)
712 eb_vp9_get_full_object(
713 full_fifo_ptr,
714 wrapper_dbl_ptr);
715 else
716 *wrapper_dbl_ptr = (EbObjectWrapper*)EB_NULL;
717
718 return return_error;
719 }
720