blob: ea4333eef0237d55f8f315e22c9805257855f0ea [file] [log] [blame]
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301/******************************************************************************
2 *
3 * Copyright (C) 2015 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *****************************************************************************
18 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19*/
20/**
21*******************************************************************************
22* @file
23* ih264_buf_mgr.c
24*
25* @brief
26* Contains function definitions for buffer management
27*
28* @author
29* Srinivas T
30*
31* @par List of Functions:
32* - ih264_buf_mgr_size()
33* - ih264_buf_mgr_lock()
34* - ih264_buf_mgr_unlock()
35* - ih264_buf_mgr_yield()
36* - ih264_buf_mgr_free()
37* - ih264_buf_mgr_init()
38* - ih264_buf_mgr_add()
39* - ih264_buf_mgr_get_next_free()
40* - ih264_buf_mgr_check_free()
41* - ih264_buf_mgr_set_status()
42* - ih264_buf_mgr_get_status()
43* - ih264_buf_mgr_get_buf()
44* - ih264_buf_mgr_get_bufid()
45* - ih264_buf_mgr_get_num_active_buf()
46*
47* @remarks
48* None
49*
50*******************************************************************************
51*/
52#include <stdio.h>
53#include <stdlib.h>
54#include "ih264_typedefs.h"
55#include "ih264_macros.h"
56#include "ih264_defs.h"
57#include "ih264_error.h"
58#include "ih264_buf_mgr.h"
59
60#include "ithread.h"
61
62/**
63*******************************************************************************
64*
65* @brief Returns size for buf queue context. Does not include buf queue buffer
66* requirements
67*
68* @par Description
69* Returns size for buf queue context. Does not include buf queue buffer
70* requirements. Buffer size required to store the bufs should be allocated in
71* addition to the value returned here.
72*
73* @returns Size of the buf queue context
74*
75* @remarks
76*
77*******************************************************************************
78*/
79WORD32 ih264_buf_mgr_size(void)
80{
81 WORD32 size;
82
83 size = sizeof(buf_mgr_t);
84 size += ithread_get_mutex_lock_size();
85
86 return size;
87}
88
89/**
90*******************************************************************************
91*
92* @brief
93* Locks the buf_mgr context
94*
95* @par Description
96* Locks the buf_mgr context by calling ithread_mutex_lock()
97*
98* @param[in] ps_buf_mgr
99* Job Queue context
100*
101* @returns IH264_FAIL if mutex lock fails else IH264_SUCCESS
102*
103* @remarks
104*
105*******************************************************************************
106*/
107IH264_ERROR_T ih264_buf_mgr_lock(buf_mgr_t *ps_buf_mgr)
108{
109 WORD32 retval;
110 retval = ithread_mutex_lock(ps_buf_mgr->pv_mutex);
111 if(retval)
112 {
113 return IH264_FAIL;
114 }
115 return IH264_SUCCESS;
116}
117
118/**
119*******************************************************************************
120*
121* @brief
122* Unlocks the buf_mgr context
123*
124* @par Description
125* Unlocks the buf_mgr context by calling ithread_mutex_unlock()
126*
127* @param[in] ps_buf_mgr
128* Job Queue context
129*
130* @returns IH264_FAIL if mutex unlock fails else IH264_SUCCESS
131*
132* @remarks
133*
134*******************************************************************************
135*/
136
137IH264_ERROR_T ih264_buf_mgr_unlock(buf_mgr_t *ps_buf_mgr)
138{
139 WORD32 retval;
140 retval = ithread_mutex_unlock(ps_buf_mgr->pv_mutex);
141 if(retval)
142 {
143 return IH264_FAIL;
144 }
145 return IH264_SUCCESS;
146
147}
148/**
149*******************************************************************************
150*
151* @brief
152* Yeilds the thread
153*
154* @par Description
155* Unlocks the buf_mgr context by calling
156* ih264_buf_mgr_unlock(), ithread_yield() and then ih264_buf_mgr_lock()
157* buf_mgr is unlocked before to ensure the buf_mgr can be accessed by other threads
158* If unlock is not done before calling yield then no other thread can access
159* the buf_mgr functions and update buf_mgr.
160*
161* @param[in] ps_buf_mgr
162* Job Queue context
163*
164* @returns IH264_FAIL if mutex lock unlock or yield fails else IH264_SUCCESS
165*
166* @remarks
167*
168*******************************************************************************
169*/
170IH264_ERROR_T ih264_buf_mgr_yield(buf_mgr_t *ps_buf_mgr)
171{
172
173 IH264_ERROR_T ret = IH264_SUCCESS;
174
175 IH264_ERROR_T rettmp;
176 rettmp = ih264_buf_mgr_unlock(ps_buf_mgr);
177 RETURN_IF((rettmp != IH264_SUCCESS), rettmp);
178
179 //ithread_usleep(10);
180 ithread_yield();
181
182 rettmp = ih264_buf_mgr_lock(ps_buf_mgr);
183 RETURN_IF((rettmp != IH264_SUCCESS), rettmp);
184 return ret;
185}
186
187
188/**
189*******************************************************************************
190*
191* @brief free the buf queue pointers
192*
193* @par Description
194* Frees the buf_mgr context
195*
196* @param[in] pv_buf
197* Memoy for buf queue buffer and buf queue context
198*
199* @returns Pointer to buf queue context
200*
201* @remarks
202* Since it will be called only once by master thread this is not thread safe.
203*
204*******************************************************************************
205*/
206IH264_ERROR_T ih264_buf_mgr_free(buf_mgr_t *ps_buf_mgr)
207{
208 WORD32 ret;
209 ret = ithread_mutex_destroy(ps_buf_mgr->pv_mutex);
210
211 if(0 == ret)
212 return IH264_SUCCESS;
213 else
214 return IH264_FAIL;
215}
216/**
217*******************************************************************************
218*
219* @brief
220* Buffer manager initialization function.
221*
222* @par Description:
223* Initializes the buffer manager structure
224*
225* @param[in] ps_buf_mgr
226* Pointer to the buffer manager
227*
228* @returns
229*
230* @remarks
231* None
232*
233*******************************************************************************
234*/
235
236
237void *ih264_buf_mgr_init(void *pv_buf)
238{
239 WORD32 id;
240 UWORD8 *pu1_buf;
241 buf_mgr_t *ps_buf_mgr;
242 pu1_buf = (UWORD8 *)pv_buf;
243
244 ps_buf_mgr = (buf_mgr_t *)pu1_buf;
245 pu1_buf += sizeof(buf_mgr_t);
246
247 ps_buf_mgr->pv_mutex = pu1_buf;
248 pu1_buf += ithread_get_mutex_lock_size();
249
250 ithread_mutex_init(ps_buf_mgr->pv_mutex);
251
252 ps_buf_mgr->i4_max_buf_cnt = BUF_MGR_MAX_CNT;
253 ps_buf_mgr->i4_active_buf_cnt = 0;
254
255 for(id = 0; id < BUF_MGR_MAX_CNT; id++)
256 {
257 ps_buf_mgr->au4_status[id] = 0;
258 ps_buf_mgr->apv_ptr[id] = NULL;
259 }
260
261 return ps_buf_mgr;
262}
263
264
265/**
266*******************************************************************************
267*
268* @brief
269* Adds and increments the buffer and buffer count.
270*
271* @par Description:
272* Adds a buffer to the buffer manager if it is not already present and
273* increments the active buffer count
274*
275* @param[in] ps_buf_mgr
276* Pointer to the buffer manager
277*
278* @param[in] pv_ptr
279* Pointer to the buffer to be added
280*
281* @returns Returns 0 on success, -1 otherwise
282*
283* @remarks
284* None
285*
286*******************************************************************************
287*/
288IH264_ERROR_T ih264_buf_mgr_add(buf_mgr_t *ps_buf_mgr,
289 void *pv_ptr,
290 WORD32 buf_id)
291{
292
293 IH264_ERROR_T ret = IH264_SUCCESS;
294 ret = ih264_buf_mgr_lock(ps_buf_mgr);
295 RETURN_IF((ret != IH264_SUCCESS), ret);
296
297 /* Check if buffer ID is within allowed range */
298 if(buf_id >= ps_buf_mgr->i4_max_buf_cnt)
299 {
300 ret = ih264_buf_mgr_unlock(ps_buf_mgr);
301 RETURN_IF((ret != IH264_SUCCESS), ret);
302
303 return IH264_FAIL;
304 }
305
306 /* Check if the current ID is being used to hold some other buffer */
307 if((ps_buf_mgr->apv_ptr[buf_id] != NULL) &&
308 (ps_buf_mgr->apv_ptr[buf_id] !=pv_ptr))
309 {
310 ret = ih264_buf_mgr_unlock(ps_buf_mgr);
311 RETURN_IF((ret != IH264_SUCCESS), ret);
312
313 return IH264_FAIL;
314 }
315 ps_buf_mgr->apv_ptr[buf_id] = pv_ptr;
316 ps_buf_mgr->i4_active_buf_cnt++;
317
318 ret = ih264_buf_mgr_unlock(ps_buf_mgr);
319 RETURN_IF((ret != IH264_SUCCESS), ret);
320
321 return ret;
322}
323
324/**
325*******************************************************************************
326*
327* @brief
328* Gets the next free buffer.
329*
330* @par Description:
331* Returns the next free buffer available and sets the corresponding status
332* to DEC
333*
334* @param[in] ps_buf_mgr
335* Pointer to the buffer manager
336*
337* @param[in] pi4_buf_id
338* Pointer to the id of the free buffer
339*
340* @returns Pointer to the free buffer
341*
342* @remarks
343* None
344*
345*******************************************************************************
346*/
347void* ih264_buf_mgr_get_next_free(buf_mgr_t *ps_buf_mgr, WORD32 *pi4_buf_id)
348{
349 WORD32 id;
350 void *pv_ret_ptr;
351 IH264_ERROR_T ret = IH264_SUCCESS;
352 ret = ih264_buf_mgr_lock(ps_buf_mgr);
353 RETURN_IF((ret != IH264_SUCCESS), NULL);
354
355 pv_ret_ptr = NULL;
356 for(id = 0; id < ps_buf_mgr->i4_active_buf_cnt; id++)
357 {
358 /* Check if the buffer is non-null and status is zero */
359 if((ps_buf_mgr->au4_status[id] == 0) && (ps_buf_mgr->apv_ptr[id]))
360 {
361 *pi4_buf_id = id;
362 /* DEC is set to 1 */
363 ps_buf_mgr->au4_status[id] = 1;
364 pv_ret_ptr = ps_buf_mgr->apv_ptr[id];
365 break;
366 }
367 }
368 ret = ih264_buf_mgr_unlock(ps_buf_mgr);
369 RETURN_IF((ret != IH264_SUCCESS), NULL);
370
371 return pv_ret_ptr;
372}
373
374
375/**
376*******************************************************************************
377*
378* @brief
379* Checks the buffer manager for free buffers available.
380*
381* @par Description:
382* Checks if there are any free buffers available
383*
384* @param[in] ps_buf_mgr
385* Pointer to the buffer manager
386*
387* @returns Returns 0 if available, -1 otherwise
388*
389* @remarks
390* None
391*
392*******************************************************************************
393*/
394IH264_ERROR_T ih264_buf_mgr_check_free(buf_mgr_t *ps_buf_mgr)
395{
396 WORD32 id;
397 IH264_ERROR_T ret = IH264_SUCCESS;
398 IH264_ERROR_T rettmp = IH264_SUCCESS;
399 rettmp = ih264_buf_mgr_lock(ps_buf_mgr);
400 RETURN_IF((rettmp != IH264_SUCCESS), ret);
401
402 ret = IH264_FAIL;
403 for(id = 0; id < ps_buf_mgr->i4_active_buf_cnt; id++)
404 {
405 if((ps_buf_mgr->au4_status[id] == 0) &&
406 (ps_buf_mgr->apv_ptr[id]))
407 {
408 ret = IH264_SUCCESS;
409 break;
410 }
411 }
412 rettmp = ih264_buf_mgr_unlock(ps_buf_mgr);
413 RETURN_IF((rettmp != IH264_SUCCESS), ret);
414
415 return ret;
416
417}
418
419
420/**
421*******************************************************************************
422*
423* @brief
424* Resets the status bits.
425*
426* @par Description:
427* resets the status bits that the mask contains (status corresponding to
428* the id)
429*
430* @param[in] ps_buf_mgr
431* Pointer to the buffer manager
432*
433* @param[in] buf_id
434* ID of the buffer status to be released
435*
436* @param[in] mask
437* Contains the bits that are to be reset
438*
439* @returns 0 if success, -1 otherwise
440*
441* @remarks
442* None
443*
444*******************************************************************************
445*/
446IH264_ERROR_T ih264_buf_mgr_release(buf_mgr_t *ps_buf_mgr,
447 WORD32 buf_id,
448 UWORD32 mask)
449{
450 IH264_ERROR_T ret = IH264_SUCCESS;
451 ret = ih264_buf_mgr_lock(ps_buf_mgr);
452 RETURN_IF((ret != IH264_SUCCESS), ret);
453
454
455 /* If the given id is pointing to an id which is not yet added */
456 if(buf_id >= ps_buf_mgr->i4_active_buf_cnt)
457 {
458 ret = ih264_buf_mgr_unlock(ps_buf_mgr);
459 RETURN_IF((ret != IH264_SUCCESS), ret);
460 return IH264_FAIL;
461 }
462
463 ps_buf_mgr->au4_status[buf_id] &= ~mask;
464
465
466/* If both the REF and DISP are zero, DEC is set to zero */
467 if(ps_buf_mgr->au4_status[buf_id] == 1)
468 {
469 ps_buf_mgr->au4_status[buf_id] = 0;
470 }
471
472
473 ret = ih264_buf_mgr_unlock(ps_buf_mgr);
474 RETURN_IF((ret != IH264_SUCCESS), ret);
475
476 return ret;
477}
478
479
480/**
481*******************************************************************************
482*
483* @brief
484* Sets the status bit.
485*
486* @par Description:
487* sets the status bits that the mask contains (status corresponding to the
488* id)
489*
490*
491* @param[in] ps_buf_mgr
492* Pointer to the buffer manager
493*
494* @param[in] buf_id
495* ID of the buffer whose status needs to be modified
496*
497*
498* @param[in] mask
499* Contains the bits that are to be set
500*
501* @returns 0 if success, -1 otherwise
502*
503* @remarks
504* None
505*
506*******************************************************************************
507*/
508IH264_ERROR_T ih264_buf_mgr_set_status(buf_mgr_t *ps_buf_mgr,
509 WORD32 buf_id,
510 UWORD32 mask)
511{
512 IH264_ERROR_T ret = IH264_SUCCESS;
513 ret = ih264_buf_mgr_lock(ps_buf_mgr);
514 RETURN_IF((ret != IH264_SUCCESS), ret);
515
516 if(buf_id >= ps_buf_mgr->i4_active_buf_cnt)
517 {
518 ret = ih264_buf_mgr_unlock(ps_buf_mgr);
519 RETURN_IF((ret != IH264_SUCCESS), ret);
520 return IH264_FAIL;
521 }
522
523
524 if((ps_buf_mgr->au4_status[buf_id] & mask) != 0)
525 {
526 ret = ih264_buf_mgr_unlock(ps_buf_mgr);
527 RETURN_IF((ret != IH264_SUCCESS), ret);
528 return IH264_FAIL;
529 }
530
531 ps_buf_mgr->au4_status[buf_id] |= mask;
532 ret = ih264_buf_mgr_unlock(ps_buf_mgr);
533 RETURN_IF((ret != IH264_SUCCESS), ret);
534
535 return ret;
536}
537
538
539/**
540*******************************************************************************
541*
542* @brief
543* Returns the status of the buffer.
544*
545* @par Description:
546* Returns the status of the buffer corresponding to the id
547*
548* @param[in] ps_buf_mgr
549* Pointer to the buffer manager
550*
551* @param[in] buf_id
552* ID of the buffer status required
553*
554* @returns Status of the buffer corresponding to the id
555*
556* @remarks
557* None
558*
559*******************************************************************************
560*/
561WORD32 ih264_buf_mgr_get_status( buf_mgr_t *ps_buf_mgr, WORD32 buf_id )
562{
563 IH264_ERROR_T ret = IH264_SUCCESS;
564 UWORD32 status;
565
566 ret = ih264_buf_mgr_lock(ps_buf_mgr);
567 RETURN_IF((ret != IH264_SUCCESS), ret);
568
569 status = ps_buf_mgr->au4_status[buf_id];
570
571 ret = ih264_buf_mgr_unlock(ps_buf_mgr);
572 RETURN_IF((ret != IH264_SUCCESS), ret);
573
574 return status;
575}
576
577
578/**
579*******************************************************************************
580*
581* @brief
582* Gets the buffer from the buffer manager
583*
584* @par Description:
585* Returns the pointer to the buffer corresponding to the id
586*
587* @param[in] ps_buf_mgr
588* Pointer to the buffer manager
589*
590* @param[in] buf_id
591* ID of the buffer required
592*
593* @returns Pointer to the buffer required
594*
595* @remarks
596* None
597*
598*******************************************************************************
599*/
600void* ih264_buf_mgr_get_buf(buf_mgr_t *ps_buf_mgr, WORD32 buf_id)
601{
602 IH264_ERROR_T ret = IH264_SUCCESS;
603 void *pv_buf;
604 ret = ih264_buf_mgr_lock(ps_buf_mgr);
605 RETURN_IF((ret != IH264_SUCCESS), NULL);
606
607 pv_buf = ps_buf_mgr->apv_ptr[buf_id];
608
609 ret = ih264_buf_mgr_unlock(ps_buf_mgr);
610 RETURN_IF((ret != IH264_SUCCESS), NULL);
611
612 return pv_buf;
613}
614
615
616/**
617*******************************************************************************
618*
619* @brief
620* Gets the buffer id from the buffer manager if the buffer is added to the
621* buffer manager
622*
623* @par Description:
624* Returns the buffer id corresponding to the given buffer if it exists
625*
626* @param[in] ps_buf_mgr
627* Pointer to the buffer manager
628*
629* @param[in] pv_buf
630* Pointer to the buffer
631*
632* @returns Buffer id if exists, else -1
633*
634* @remarks
635* None
636*
637*******************************************************************************
638*/
639WORD32 ih264_buf_mgr_get_bufid(buf_mgr_t *ps_buf_mgr, void *pv_buf)
640{
641 WORD32 id;
642 WORD32 buf_id = -1;
643 IH264_ERROR_T ret = IH264_SUCCESS;
644 ret = ih264_buf_mgr_lock(ps_buf_mgr);
645 RETURN_IF((ret != IH264_SUCCESS), ret);
646
647 for(id = 0; id < ps_buf_mgr->i4_active_buf_cnt; id++)
648 {
649 if(ps_buf_mgr->apv_ptr[id] == pv_buf)
650 {
651 buf_id = id;
652 break;
653 }
654 }
655 ret = ih264_buf_mgr_unlock(ps_buf_mgr);
656 RETURN_IF((ret != IH264_SUCCESS), ret);
657
658 return buf_id;
659}
660
661
662/**
663*******************************************************************************
664*
665* @brief
666* Gets the no.of active buffer
667*
668* @par Description:
669* Return the number of active buffers in the buffer manager
670*
671* @param[in] ps_buf_mgr
672* Pointer to the buffer manager
673*
674* @returns number of active buffers
675*
676* @remarks
677* None
678*
679*******************************************************************************
680*/
681UWORD32 ih264_buf_mgr_get_num_active_buf(buf_mgr_t *ps_buf_mgr)
682{
683 UWORD32 u4_buf_cnt;
684 IH264_ERROR_T ret = IH264_SUCCESS;
685
686 u4_buf_cnt = 0;
687
688 ret = ih264_buf_mgr_lock(ps_buf_mgr);
689 RETURN_IF((ret != IH264_SUCCESS), ret);
690 u4_buf_cnt = ps_buf_mgr->i4_active_buf_cnt;
691
692 ret = ih264_buf_mgr_unlock(ps_buf_mgr);
693 RETURN_IF((ret != IH264_SUCCESS), ret);
694
695 return u4_buf_cnt;
696}