source: svn/newcon3bcm2_21bu/magnum/syslib/vbilib/bvbilib_dccreorder.c

Last change on this file was 76, checked in by megakiss, 10 years ago

1W 대기전력을 만족시키기 위하여 POWEROFF시 튜너를 Standby 상태로 함

  • Property svn:executable set to *
File size: 12.4 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2007, Broadcom Corporation
3 *     All Rights Reserved
4 *     Confidential Property of Broadcom Corporation
5 *
6 *  THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE
7 *  AGREEMENT  BETWEEN THE USER AND BROADCOM.  YOU HAVE NO RIGHT TO USE OR
8 *  EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
9 *
10 * $brcm_Workfile: bvbilib_dccreorder.c $
11 * $brcm_Revision: Hydra_Software_Devel/4 $
12 * $brcm_Date: 5/29/07 2:32p $
13 *
14 * Module Description:
15 *
16 * Revision History:
17 *
18 * $brcm_Log: /magnum/syslib/vbilib/bvbilib_dccreorder.c $
19 *
20 * Hydra_Software_Devel/4   5/29/07 2:32p darnstein
21 * PR31097: Bug fix: I forgot to advance a queue pointer.
22 *
23 * Hydra_Software_Devel/3   5/29/07 1:11p darnstein
24 * PR31097: Implement the _Count function. Fix some ordinary typing
25 * errors. Add another paramter check to the _Open function.
26 *
27 * Hydra_Software_Devel/2   5/25/07 6:09p darnstein
28 * PR31097: ready for testing now.
29 *
30 * Hydra_Software_Devel/1   5/25/07 1:51p darnstein
31 * PR31097: just a placeholder for now.
32 *
33 ***************************************************************************/
34
35#include "bvbilib_dccreorder.h"
36#include "bkni.h"
37
38BDBG_MODULE(BVBIlib);
39
40/***************************************************************************
41* Private data structures
42***************************************************************************/
43
44/* This is an entry in one of the queues of closed caption data */
45typedef struct
46{
47    uint8_t datumL;
48    uint8_t datumH;
49}
50P_CCdata;
51
52/* This is a queue of closed caption data */
53typedef struct
54{
55        unsigned int size;
56        unsigned int readN;
57        unsigned int writeN;
58        P_CCdata* array;
59}
60P_Queue;
61
62/* This is the complete state of the module */
63typedef struct
64{
65        uint32_t ulBlackMagic;
66        P_Queue topQ;
67        P_Queue botQ;
68        unsigned int threshold;
69        BAVC_Polarity last_rtn_polarity;
70}
71BVBIlib_P_DCCReorder_Handle;
72
73/***************************************************************************
74* Forward declarations of static (private) functions
75***************************************************************************/
76
77/* This is also defined in bvbilib_priv.h. I decided to keep these files
78 * independent of each other.
79 */
80#define BVBILIB_P_GENERIC_GET_CONTEXT(handle, context, structname) \
81do { \
82        if(!(handle) || \
83           (((structname*)(handle))->ulBlackMagic != \
84           sizeof(structname))) \
85        { \
86                BDBG_ERR(("Corrupted context handle\n")); \
87                (context) = NULL; \
88        } \
89        else \
90        { \
91                (context) = (structname*)(handle); \
92        } \
93} while (0)
94
95#define P_GET_CONTEXT(handle, context) \
96        BVBILIB_P_GENERIC_GET_CONTEXT(handle, context, BVBIlib_P_DCCReorder_Handle)
97
98#ifndef MAX
99        #define MAX(a,b) (((a) > (b)) ? (a) : (b))
100#endif
101
102static BERR_Code P_Put (P_Queue* queue, uint8_t datumL, uint8_t datumH);
103static BERR_Code P_Get (P_Queue* queue, uint8_t* pDatumL, uint8_t* pDatumH);
104static unsigned int P_Count (P_Queue* queue);
105
106/***************************************************************************
107* Implementation of "BVBIlib_" API functions
108***************************************************************************/
109
110/***************************************************************************
111 *
112 */
113BERR_Code BVBIlib_DCCReorder_Open (
114    BVBIlib_DCCReorder_Handle* pHandle, 
115    unsigned int histSize,             
116    unsigned int threshold             
117)
118{
119        BVBIlib_P_DCCReorder_Handle *prHandle;
120        unsigned int vtest;
121        unsigned int count = 0;
122
123        BDBG_ENTER(BVBIlib_DCCReorder_Open);
124
125        if (!pHandle) 
126        {
127                BDBG_ERR(("Invalid parameter\n"));
128                BDBG_LEAVE(BVBIlib_DCCReorder_Open);
129                return BERR_TRACE(BERR_INVALID_PARAMETER);
130        }
131
132        /* Verify that the size parameter is nonzero, and a power of two. */
133        if (histSize == 0)
134        {
135                BDBG_ERR(("Invalid parameter\n"));
136                BDBG_LEAVE(BVBIlib_DCCReorder_Open);
137                return BERR_TRACE(BERR_INVALID_PARAMETER);
138        }
139        vtest = histSize;
140        while (vtest > 1)
141        {
142                ++count;
143                vtest >>= 1;
144        }
145        vtest = 1 << count;
146        if (vtest != histSize)
147        {
148                BDBG_ERR(("Invalid parameter\n"));
149                BDBG_LEAVE(BVBIlib_DCCReorder_Open);
150                return BERR_TRACE(BERR_INVALID_PARAMETER);
151        }
152
153        /* Don't allow a large threshold */
154        if (threshold > histSize)
155        {
156                BDBG_ERR(("Invalid parameter\n"));
157                BDBG_LEAVE(BVBIlib_DCCReorder_Open);
158                return BERR_TRACE(BERR_INVALID_PARAMETER);
159        }
160
161        /* Alloc the main context. */
162        prHandle = 
163                (BVBIlib_P_DCCReorder_Handle*)(BKNI_Malloc(
164                        sizeof(BVBIlib_P_DCCReorder_Handle)));
165
166        if(!prHandle)
167        {
168                return BERR_TRACE(BERR_OUT_OF_SYSTEM_MEMORY);
169        }
170
171        /* Clear out the context and set defaults. */
172        BKNI_Memset((void*)prHandle, 0x0, sizeof(BVBIlib_P_DCCReorder_Handle));
173
174        /* Allocate queues */
175        prHandle->topQ.array = (P_CCdata*)BKNI_Malloc (
176                histSize * sizeof(P_CCdata));
177        if (!prHandle->topQ.array)
178        {
179                BKNI_Free ((void*)prHandle);
180                return BERR_TRACE(BERR_OUT_OF_SYSTEM_MEMORY);
181        }
182        prHandle->botQ.array = (P_CCdata*)BKNI_Malloc (
183                histSize * sizeof(P_CCdata));
184        if (!prHandle->botQ.array)
185        {
186                BKNI_Free ((void*)(prHandle->topQ.array));
187                BKNI_Free ((void*)prHandle);
188                return BERR_TRACE(BERR_OUT_OF_SYSTEM_MEMORY);
189        }
190
191        /* Store user's settings */
192        prHandle->topQ.size = histSize;
193        prHandle->botQ.size = histSize;
194        prHandle->threshold = threshold;
195
196        /* Initialize empty queues of closed caption data */
197        prHandle->topQ.readN  = 0;
198        prHandle->topQ.writeN = 0;
199        prHandle->botQ.readN  = 0;
200        prHandle->botQ.writeN = 0;
201
202        /* The module has returned no CC data yet */
203        prHandle->last_rtn_polarity = BAVC_Polarity_eFrame;    /* undefined */
204
205        /* Initialize magic number to the size of the struct */
206        prHandle->ulBlackMagic = sizeof(BVBIlib_P_DCCReorder_Handle);
207
208        /* All done. now return the new fresh context to user. */
209        *pHandle = (BVBIlib_DCCReorder_Handle)prHandle;
210
211        BDBG_LEAVE(BVBIlib_DCCReorder_Open);
212        return BERR_SUCCESS;
213}
214
215
216/***************************************************************************
217 *
218 */
219void BVBIlib_DCCReorder_Close (BVBIlib_DCCReorder_Handle handle)
220{
221        BVBIlib_P_DCCReorder_Handle *prHandle;
222
223        BDBG_ENTER(BVBIlib_DCCReorder_Close);
224
225        /* check parameters */
226        P_GET_CONTEXT(handle, prHandle);
227        BDBG_ASSERT (prHandle != NULL);
228
229        /* The handle is about to become invalid */
230        prHandle->ulBlackMagic = 0;
231
232        /* Release context in system memory */
233        BKNI_Free ((void*)(prHandle->topQ.array));
234        BKNI_Free ((void*)(prHandle->botQ.array));
235        BKNI_Free((void*)prHandle);
236
237        BDBG_LEAVE(BVBIlib_DCCReorder_Close);
238}
239
240
241/***************************************************************************
242 *
243 */
244BERR_Code BVBIlib_DCCReorder_Put (
245    BVBIlib_DCCReorder_Handle handle,
246    uint8_t datumL,                 
247    uint8_t datumH,
248    BAVC_Polarity polarity
249)
250{
251        BVBIlib_P_DCCReorder_Handle *prHandle;
252        P_Queue* queue;
253        BERR_Code eStatus;
254
255        BDBG_ENTER (BVBIlib_DCCReorder_Put);
256
257        /* check parameters */
258        P_GET_CONTEXT(handle, prHandle);
259        if (prHandle == NULL)
260        {
261                return BERR_TRACE (BERR_INVALID_PARAMETER);
262        }
263
264        /* Choose a queue to operate on */
265        switch (polarity)
266        {
267        case BAVC_Polarity_eTopField:
268                queue = &(prHandle->topQ);
269                break;
270        case BAVC_Polarity_eBotField:
271                queue = &(prHandle->botQ);
272                break;
273        default:
274                queue = 0x0;
275                return BERR_TRACE (BERR_INVALID_PARAMETER);
276                break;
277        }
278
279        /* Store the data if there is room */
280        eStatus = P_Put (queue, datumL, datumH);
281
282        BDBG_LEAVE (BVBIlib_DCCReorder_Put);
283        return eStatus;
284}
285
286
287/***************************************************************************
288 *
289 */
290BERR_Code BVBIlib_DCCReorder_Get (
291    BVBIlib_DCCReorder_Handle handle, 
292    uint8_t* pDatumL,                   
293    uint8_t* pDatumH,                   
294    BAVC_Polarity* pPolarity           
295)
296{
297        BVBIlib_P_DCCReorder_Handle *prHandle;
298        P_Queue* queue;
299        uint8_t datumL = 0x0;
300        uint8_t datumH = 0x0;
301        BAVC_Polarity polarity = BAVC_Polarity_eFrame;
302        BERR_Code eStatus = BERR_OUT_OF_SYSTEM_MEMORY;
303
304        BDBG_ENTER (BVBIlib_DCCReorder_Get);
305
306        /* check parameters */
307        P_GET_CONTEXT(handle, prHandle);
308        if (prHandle == NULL)
309        {
310                return BERR_TRACE (BERR_INVALID_PARAMETER);
311        }
312
313        /*
314         * This is the core algorithm of the entire BVBIlib_dccreorder module. See
315         * description of this function in bvbilib_dccreorder.h for details.
316         */
317
318        /* Special case: no data returned yet. Any polarity data will do. */
319        if (prHandle->last_rtn_polarity == BAVC_Polarity_eFrame)
320        {
321                if ((eStatus = P_Get (&prHandle->topQ, &datumL, &datumH)) == 
322                        BERR_SUCCESS)
323                {
324                        prHandle->last_rtn_polarity = BAVC_Polarity_eTopField;
325                        polarity                    = BAVC_Polarity_eTopField;
326                }
327                else
328                {
329                        if ((eStatus = P_Get (&prHandle->botQ, &datumL, &datumH)) ==
330                                BERR_SUCCESS)
331                        {
332                                prHandle->last_rtn_polarity = BAVC_Polarity_eBotField;
333                                polarity                    = BAVC_Polarity_eBotField;
334                        }
335                }
336        }
337
338        /* Next, try to maintain alternating polarity. */
339        if (eStatus != BERR_SUCCESS)
340        {
341                if (prHandle->last_rtn_polarity == BAVC_Polarity_eTopField)
342                {
343                        queue = &prHandle->botQ;
344                        polarity = BAVC_Polarity_eBotField;
345                }
346                else
347                {
348                        queue = &prHandle->topQ;
349                        polarity = BAVC_Polarity_eTopField;
350                }
351                eStatus = P_Get (queue, &datumL, &datumH);
352                if (eStatus == BERR_SUCCESS)
353                {
354                        prHandle->last_rtn_polarity = polarity;
355                }
356        }
357
358        /* Next, check for a too-full top queue. */
359        if (eStatus != BERR_SUCCESS)
360        {
361                if (P_Count (&prHandle->topQ) + prHandle->threshold > 
362                        prHandle->topQ.size)
363                {
364                        eStatus = P_Get (&prHandle->topQ, &datumL, &datumH);
365                        if (eStatus == BERR_SUCCESS)
366                        {
367                                prHandle->last_rtn_polarity = BAVC_Polarity_eTopField;
368                                polarity                    = BAVC_Polarity_eTopField;
369                        }
370                }
371        }
372
373        /* Finally, check for a too-full bottom queue. */
374        if (eStatus != BERR_SUCCESS)
375        {
376                if (P_Count (&prHandle->botQ) + prHandle->threshold > 
377                        prHandle->botQ.size)
378                {
379                        eStatus = P_Get (&prHandle->botQ, &datumL, &datumH);
380                        if (eStatus == BERR_SUCCESS)
381                        {
382                                prHandle->last_rtn_polarity = BAVC_Polarity_eBotField;
383                                polarity                    = BAVC_Polarity_eBotField;
384                        }
385                }
386        }
387
388        /* Return what we got */
389        if (eStatus == BERR_SUCCESS)
390        {
391                *pDatumL   = datumL;
392                *pDatumH   = datumH;
393                *pPolarity = polarity;
394        }
395
396        BDBG_LEAVE (BVBIlib_DCCReorder_Get);
397        return eStatus;
398}
399
400
401/***************************************************************************
402 *
403 */
404BERR_Code BVBIlib_DCCReorder_Count (
405    BVBIlib_DCCReorder_Handle* handle, 
406    unsigned int* count               
407)
408{
409        BVBIlib_P_DCCReorder_Handle *prHandle;
410
411        BDBG_ENTER (BVBIlib_DCCReorder_Count);
412
413        /* check parameters */
414        P_GET_CONTEXT(handle, prHandle);
415        if (prHandle == NULL)
416        {
417                return BERR_TRACE (BERR_INVALID_PARAMETER);
418        }
419
420        *count = MAX (P_Count (&prHandle->topQ), P_Count (&prHandle->botQ));
421
422        BDBG_LEAVE (BVBIlib_DCCReorder_Count);
423        return BERR_SUCCESS;
424}
425
426/***************************************************************************
427* Implementation of private (static) functions
428***************************************************************************/
429
430/*
431 * Rules for the queues:
432 * --------------------
433 *
434 *  The queue size must be a power of two.
435 *
436 *  A queue is empty when readN == writeN
437 *
438 *  A queue is full when readN != writeN AND (readN == writeN (modulo size))
439 *
440 *  Increment one counter on every read and write. No other counter
441 *  modification is allowed.
442 */
443
444/***************************************************************************
445 *
446 */
447static BERR_Code P_Put (P_Queue* queue, uint8_t datumL, uint8_t datumH)
448{
449        unsigned int index;
450        P_CCdata* ccdata;
451
452        /* Check for queue full condition */
453        if (queue->readN != queue->writeN)
454        {
455                if (((queue->writeN - queue->readN) % queue->size) == 0)
456                {
457                        return BERR_OUT_OF_SYSTEM_MEMORY;
458                }
459        }
460
461        /* Queue not full, work it. */
462        index = (queue->writeN) % (queue->size);
463        ccdata = &queue->array[index];
464        ccdata->datumL = datumL;
465        ccdata->datumH = datumH;
466
467        /* Advance the queue */
468        ++(queue->writeN);
469
470        /* Success */
471        return BERR_SUCCESS;
472}
473
474/***************************************************************************
475 *
476 */
477static BERR_Code P_Get (P_Queue* queue, uint8_t* pDatumL, uint8_t* pDatumH)
478{
479        unsigned int index;
480        P_CCdata* ccdata;
481
482        /* Check for queue empty condition */
483        if (queue->readN == queue->writeN)
484        {
485                return BERR_OUT_OF_SYSTEM_MEMORY;
486        }
487
488        /* Queue not empty, work it. */
489        index = (queue->readN) % (queue->size);
490        ccdata = &queue->array[index];
491        *pDatumL = ccdata->datumL;
492        *pDatumH = ccdata->datumH;
493
494        /* Advance the queue */
495        ++(queue->readN);
496
497        /* Success */
498        return BERR_SUCCESS;
499}
500
501/***************************************************************************
502 *
503 */
504static unsigned int P_Count (P_Queue* queue)
505{
506        unsigned int count = 0;
507
508        if (queue->writeN < queue->readN)
509        {
510                count = queue->size;
511        }
512
513        count += queue->writeN;
514        count -= queue->readN;
515
516        return count;
517}
Note: See TracBrowser for help on using the repository browser.