source: svn/trunk/newcon3bcm2_21bu/dta/src/dcc/src/bdccengine.c @ 2

Last change on this file since 2 was 2, checked in by jglee, 11 years ago

first commit

  • Property svn:executable set to *
File size: 37.2 KB
Line 
1/***************************************************************************         
2 *     Copyright (c) 2002-2006, 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: bdccengine.c $
11 * $brcm_Revision: 14 $
12 * $brcm_Date: 10/4/06 1:58p $
13 *     
14 * Module Description:               
15 *         
16 * Revision History:         
17 *     
18 * $brcm_Log: /BSEAV/lib/ccgfx/source/bdccengine.c $
19 *
20 * 14   10/4/06 1:58p btosi
21 * PR22275: fixed issues with the selection of the 608 service (CC 1-4)
22 * need to pass"Field" and "Channel" to BDCC_608_TranscodeReset, treat
23 * "Field" as a zero-based index.
24 *
25 * 13   9/22/06 1:33p btosi
26 * PR22275: added support for clearing the screen if the CC data stream
27 * stops for an extended period (30 seconds)
28 *
29 * 12   9/15/06 12:07p btosi
30 * PR22275: added support for font edges
31 *
32 * 11   8/23/06 9:00a btosi
33 * PR22275: added support for specifying the "Safe Title" area
34 *
35 * 10   8/17/06 1:13p btosi
36 * PR22275: reworked the API to support loading/unloading fonts files
37 *
38 * 9   8/4/06 4:03p btosi
39 * PR22275: cleaned up the processing of the DELAY command.
40 *
41 * 8   8/3/06 12:07p btosi
42 * PR22275: cleaned up the flashing implementation which uses two
43 * surfaces, i.e. FLASH_BY_2SURFACES
44 *
45 * 7   7/28/06 1:27p btosi
46 * PR22275: cleaned up build warnings
47 *
48 * 6   7/17/06 1:35p btosi
49 * PR22275: added wrapper routine BDCC_ENG_Process, support for resetting
50 * the library and logic to update the time counter
51 *
52 * 5   7/7/06 12:31p btosi
53 * PR22275: added logic to redraw the framebuffer less frequently
54 *
55 * 4   5/10/06 6:49p shyam
56 * PR 8365 : Make it comiler warning free and ANSI C compliant
57 *
58 * 3   4/6/06 2:51p btosi
59 * PR3541: adding use of the BDBG_MODULE macro for integration with the
60 * RNG200 build
61 *
62 * 2   5/17/05 7:44p shyam
63 * PR 8365 : Making it work at runtime
64 *
65 * 1   5/9/05 3:49p shyam
66 * PR 8365 : Add other sub-modules of ccgfx
67 *
68 ***************************************************************************/   
69 
70
71
72
73
74
75/***************************************************************************
76 *                         708 Rendering Engine
77 *                         --------------------
78 *
79 * This Rendering Engine API is a wrapper around several lower-level 708
80 * libraries.  In most cases, it is expected that this API will be used
81 * instead of the lower-level APIs.  In those cases in which the customer/
82 * system integrator has a need that isn't covered here, this code then
83 * serves as example code.
84 *
85 * Scope
86 *
87 * This API wraps the 708 DTVCC rendering and 608 Transcoding libraries
88 * but does not wrap the APIs used to extract Closed Captioning streams
89 * from MPEG User Data or from analog Line 21.  Furthermore, it does not
90 * wrap the API for inserting 608 back into Line 21 on analog output.
91 *
92 * 608 and 708
93 *
94 * The Rendering Engine has two main entry points, one each for 708 rendering
95 * and 608 transcoding.  Higher level system/driver code is expected to call the
96 * appropriate API to extract the Closed Captioning data from the input, be it
97 * the MPEG API (ie., bcmMPIReadClosedCaptionStatus) or the CCDecoder API
98 * (bCCDProcess), and then call one of these two entry points in this API:
99 * BDCC_ENG_Process608 or DccEngine_Process708.
100 *
101 * This API has these features:
102 *
103 * 1.  manages the circular buffers
104 * 2.  sequences the calls to the lower-level APIs
105 * 3.  allows caller control over field and service numbers
106 * 4.  allows caller ability to override various DTVCC attributes
107 * 5.  provides reset
108 * 6.  context-less:  all processing done on _ProcessXxx and _Periodic calls
109 *
110 ***************************************************************************/   
111
112
113                                /*********************
114                                 *
115                                 * Includes
116                                 *
117                                 *********************/
118
119
120#include "bdcc_cfg.h"
121#include "bdcc_kernel.h"
122#include "bdcc.h"
123#include "bdcc_cbuf.h"
124#include "bdcc_coding.h"
125#include "bdccpacket.h"
126#include "bdcc608transcoder.h"
127
128#include "bdccengine.h"
129#include "bdccservice.h"
130#include "bdccintgfx.h"
131
132BDBG_MODULE(bdccengine);
133                                /*********************
134                                 *
135                                 * Defines
136                                 *
137                                 *********************/
138#define BDCC_ENG_P_ASPECT_4_3_COLUMN_SIZE       32
139#define BDCC_ENG_P_ASPECT_16_9_COLUMN_SIZE      42
140#define BDCC_ENG_P_DEF_CHARCELL_WIDTH           15
141#define BDCC_ENG_P_DEF_CHARCELL_HEIGHT          25
142
143#define BDCC_ENG_P_CBUF_SIZE                            512
144
145#define BDCC_ENG_P_CBUF_RESERVE                 32
146#define BDCC_ENG_P_SILIMIT_608                          (BDCC_ENG_P_CBUF_SIZE - BDCC_ENG_P_CBUF_RESERVE)
147/*
148** BDCC_ENG_P_SILIMIT_708 was originally defined to be 128.
149** I don't see any reason that this can't be the entire buffer minus "a bit".  7/7/06
150*/
151#define BDCC_ENG_P_SILIMIT_708                          (BDCC_ENG_P_CBUF_SIZE - (2 * BDCC_ENG_P_CBUF_RESERVE))
152
153/*
154** How much the CC window needs to be indented to insure
155** that it is visible.
156** These really should be set by the application based on the
157** screen resolution and display type.
158*/
159#define BDCC_ENG_P_SafeTitle_X    36 /* TODO: originally this was 40, what should it be?*/
160#define BDCC_ENG_P_SafeTitle_Y    24 /* TODO: originally this was 30, what should it be?*/
161
162
163                                /*********************
164                                 *
165                                 * Types
166                                 *
167                                 *********************/
168typedef struct BDCC_ENG_P_Object
169{
170        /*
171         * Circular Buffer:  Triplets
172         *
173         * This buffer holds either 608 or 708 byte
174         * triplets:  (field,cc1,cc2) or (cc_type,cc1,cc2)
175         */
176        BDCC_CBUF               cbTriplets ;
177        unsigned char   BufTriplets[BDCC_ENG_P_CBUF_SIZE*3] ;
178       
179        /*
180         * Circular Buffer:  Packet
181         *
182         * This buffer holds 708 packets, used only for
183         * DTVCC processing, not for 608 transcoding
184         */
185        BDCC_CBUF               cbPacket ;
186        unsigned char   BufPacket[BDCC_ENG_P_CBUF_SIZE] ;
187       
188        /*
189         * Circular Buffer:  Service
190         *
191         * This buffer holds 708 service blocks.
192         */
193        BDCC_CBUF               cbService ;
194        unsigned char   BufService[BDCC_ENG_P_CBUF_SIZE] ;
195       
196        /*
197         * Circular Buffer:  Coding
198         *
199         * This buffer feeds the coding and interpretation
200         * library.  This also serves as the Service Input
201         * Buffer, per the 708 spec.
202         */
203        BDCC_CBUF               cbCoding ;
204        unsigned char   BufCoding[BDCC_ENG_P_CBUF_SIZE] ;
205
206        /*
207         * associated object data
208         */
209        BDCC_608_hTranscoder    h608Transcoder ;
210        BDCC_INT_P_Handle               hCodingInt ;
211        BDCC_PKT_P_Object               PacketObject ;
212        /* The CCGFX Winlib module handle */
213        BCCGFX_WINLIB_P_Handle  hWinLibHandle ;
214        /* The CCGFX module handle */
215        BCCGFX_P_GfxHandle              hCCGfxHandle ;
216
217        /*
218         * object attributes
219         */
220        BDCC_ENG_Type   Type ;
221        int                             iCcService ;
222       
223        BDCC_ENG_Settings engineSettings;
224        unsigned int    SILimit ;
225       
226        unsigned int    uiCurTimeMilliSecs;     /* roughtly the current system                                      */
227        unsigned int    uiLastDataMilliSecs;    /* the last time CC data was received                           */
228        bool                bDataReceived;          /* data has been received since the last screen clear   */
229       
230        //RLQ
231        int                             iCcService708;                  /* track the 708 CS user selected */
232        unsigned int    uiLastCSMilliSecs;              /* the last time CC data was received                           */
233        uint32_t                iPktSequenceNumErr;             /* track packet sequence number error */
234} BDCC_ENG_P_Object ;
235                                 
236
237
238
239                                /*********************
240                                 *
241                                 * Prototypes
242                                 *
243                                 *********************/
244                                 
245BDCC_Error CheckForBufferOverflow(BDCC_ENG_Handle hEngine) ;
246void ResetDownstreamOfPacket(BDCC_ENG_Handle hEngine);
247
248
249BDCC_Error BDCC_ENG_P_Init(
250        bool bResetOnly,
251        BDCC_ENG_Handle hEngine, 
252        BDCC_ENG_Type Type,
253        BCCGFX_WINLIB_P_Handle hWinLibHandle,
254        int iCcService
255        )
256{
257        unsigned int SILimit ;
258    BDCC_608_hTranscoder h608Transcoder = NULL  ;
259    BCCGFX_P_GfxHandle hCCGfxHandle = NULL ;
260    BDCC_INT_P_Handle hCodingInt = NULL ;
261
262        /*
263    ** save the current parameters
264         */
265        hEngine->hWinLibHandle = hWinLibHandle ;
266        hEngine->Type = Type ;
267    hEngine->iCcService = iCcService ;
268    hEngine->bDataReceived = false ;
269
270    /*
271    ** TODO: is the following code block really needed?
272    */
273        if(bResetOnly)
274        {
275                h608Transcoder  = hEngine->h608Transcoder ;
276                hCCGfxHandle = hEngine->hCCGfxHandle ;
277                hCodingInt = hEngine->hCodingInt ;
278        }
279       
280        /*
281    ** init the circular buffers
282         */
283        BDCC_CBUF_Init(&hEngine->cbTriplets, hEngine->BufTriplets, sizeof(hEngine->BufTriplets), BDCC_ENG_P_CBUF_RESERVE) ;
284        BDCC_CBUF_Init(&hEngine->cbPacket, hEngine->BufPacket, sizeof(hEngine->BufPacket), BDCC_ENG_P_CBUF_RESERVE) ;
285        BDCC_CBUF_Init(&hEngine->cbService, hEngine->BufService, sizeof(hEngine->BufService), BDCC_ENG_P_CBUF_RESERVE) ;
286        BDCC_CBUF_Init(&hEngine->cbCoding, hEngine->BufCoding, sizeof(hEngine->BufCoding), BDCC_ENG_P_CBUF_RESERVE) ;
287
288        /*
289    ** if we're doing 608 transcoding init its object structure
290         */
291        if ( Type == BDCC_ENG_Type_e608 )
292        {
293                int Field608, Chan608 ;
294        switch ( iCcService )
295        {       
296                        case 1:
297                                Field608 = 1 ;
298                                Chan608 = 1 ;
299                                break ;
300                        case 2:
301                                Field608 = 1 ;
302                                Chan608 = 2 ;
303                                break ;
304                        case 3:
305                                Field608 = 2 ;
306                                Chan608 = 1 ;
307                                break ;
308                        case 4:
309                                Field608 = 2 ;
310                                Chan608 = 2 ;
311                                break ;
312                        default:
313                                return(BDCC_Error_eArgOutOfRange) ;
314                                break ;
315                }
316
317        /*
318        ** If the library is being reset and the transcode engine has previously been
319        ** opened, simply reset the transcode logic.  Otherwise allocate it.
320        **
321        ** TODO: can't we simply look at  "hEngine->h608Transcoder" to determine if we
322        ** need to reset or allocate?
323        */
324        if ( bResetOnly && h608Transcoder )
325        {
326                        hEngine->h608Transcoder = h608Transcoder ;
327            BDCC_608_TranscodeReset(hEngine->h608Transcoder, Field608, Chan608);
328        }
329        else
330        {
331            BDCC_608_TranscodeOpen(&hEngine->h608Transcoder, Field608, Chan608) ;       
332        }
333
334                SILimit = BDCC_ENG_P_SILIMIT_608 ;
335
336    }
337        else if ( Type == BDCC_ENG_Type_e708 )
338        {
339                SILimit = BDCC_ENG_P_SILIMIT_708 ;
340        hEngine->iCcService708 = iCcService ;
341        hEngine->uiLastCSMilliSecs = hEngine->uiCurTimeMilliSecs;
342        }
343        else
344        {
345                BKNI_Free(hEngine);
346                return(BDCC_Error_eArgOutOfRange) ;
347        }
348
349        /*
350    * * init the pkt, coding and interpretation objects
351    ** TODO: wrap in "bResetOnly"?
352         */
353        BDCC_PKT_P_Init(&hEngine->PacketObject) ;
354        hEngine->SILimit = SILimit ;
355
356        if(bResetOnly)
357        {
358                hEngine->hCCGfxHandle = hCCGfxHandle ;
359                hEngine->hCodingInt = hCodingInt ;
360        /*
361        ** TODO: are the following in the correct order?
362        */
363                BDCC_Coding_P_Reset(hEngine->hCodingInt) ;
364        BCCGFX_P_Reset( hEngine->hCCGfxHandle, &hEngine->engineSettings );
365    }
366        else
367        {
368                /*
369        ** init the ccgfx layer
370                 */
371
372        BCCGFX_P_Init( hEngine->hCCGfxHandle, &hEngine->engineSettings );
373
374                BDCC_Coding_P_Open(&hEngine->hCodingInt, 
375                        hEngine->hWinLibHandle, 
376                        hEngine->hCCGfxHandle, 
377                        hEngine->SILimit, 
378                    hEngine->engineSettings.Columns );
379    }
380
381    /*
382    ** Resample the system clock.
383    */
384    BCCGFX_P_TimeReset( hEngine->hCCGfxHandle );
385
386        //RLQ
387        hEngine->iPktSequenceNumErr = 0;
388
389        return(BDCC_Error_eSuccess) ;
390
391}
392
393                                /*********************
394                                 *
395                                 * API Entry Points
396                                 *
397                                 *********************/
398
399/**************************************************************************               
400 * 
401 * Function:            BDCC_ENG_GetDefaultSettings   
402 *     
403 * Inputs:                       
404 *                                      Type                            - BDCC_ENG_Type_e608 or
405 *                                                                      BDCC_ENG_Type_e708
406 *                                      pEngineSettings         - BDCC_ENG_Settings structure
407 *   
408 * Outputs:                           
409 *                                      hEngine                         - init'ed by this function
410 * 
411 * Returns:                     BDCC_Error_eSuccess or standard BDCC_Error error code     
412 *   
413 * Description:               
414 *         
415 * This function return the default and recommended values for various engine settings.
416 *
417 * See Also:
418 *    BDCC_ENG_Open
419 *               
420 **************************************************************************/ 
421BDCC_Error BDCC_ENG_GetDefaultSettings(
422        BDCC_ENG_Settings *pEngineSettings)
423{
424        BDCC_ASSERT(pEngineSettings);
425       
426        pEngineSettings->Columns = BDCC_ENG_P_ASPECT_4_3_COLUMN_SIZE ;
427        pEngineSettings->iCharCellWidth           = BDCC_ENG_P_DEF_CHARCELL_WIDTH ;
428        pEngineSettings->iCharCellHeight          = BDCC_ENG_P_DEF_CHARCELL_HEIGHT ;
429        pEngineSettings->iSafeTitleX                 = BDCC_ENG_P_SafeTitle_X;
430        pEngineSettings->iSafeTitleY                 = BDCC_ENG_P_SafeTitle_Y;
431        pEngineSettings->iEdgeWidth                 = BDCC_Edge_Width;
432        pEngineSettings->uiTimeOutMilliSecs      = BDCC_Data_Timeout_MSecs;
433
434        return BDCC_Error_eSuccess ;
435}
436
437BDCC_Error BDCC_ENG_GetSettings(
438        BDCC_ENG_Handle hEngine, 
439        BDCC_ENG_Settings *pEngineSettings
440        )
441{
442        BDCC_ASSERT(hEngine);
443        BDCC_ASSERT(pEngineSettings);
444
445        *pEngineSettings = hEngine->engineSettings;
446
447        return BDCC_Error_eSuccess ;
448}
449
450
451BDCC_Error BDCC_ENG_SetSettings(
452        BDCC_ENG_Handle hEngine, 
453        BDCC_ENG_Settings *pEngineSettings
454        )
455{
456        BDCC_ASSERT(hEngine);
457        BDCC_ASSERT(pEngineSettings);
458
459        hEngine->engineSettings = *pEngineSettings;
460
461        return BDCC_Error_eSuccess ;
462}
463
464
465/**************************************************************************               
466 * 
467 * Function:            BDCC_ENG_Open   
468 *     
469 * Inputs:                       
470 *                                      Type                            - BDCC_ENG_Type_e608 or BDCC_ENG_Type_e708
471 *                                      iCcService                              - CCx for 608 (1 to 4)
472 *                                                                                Service Number for 708 (0 to 63)
473 *                                      Columns                         - number of columns for DTVCC grid
474 *                                                                                use 32 for 4:3 and 42 for 16:9
475 *                                      iCharCellWidth          - pixel width for char cell, must be
476 *                                                                                compatible with font/glyph design
477 *                                      iCharCellHeight         - pixel height for char cell, must be
478 *                                                                                compatible with font/glyph design
479 *   
480 * Outputs:                           
481 *                                      hEngine                         - init'ed by this function   
482 * 
483 * Returns:                     BDCC_Error_eSuccess or standard BDCC_Error error code     
484 *   
485 * Description:               
486 *         
487 * This function inits the buffers used for 708 DTVCC Closed     
488 * Captioning processing.  The 'Type' argument, in effect, is announcing
489 * which processing entry point will be called during normal processing.
490 * To switch between 608 and 708 (or to switch any of the init args),
491 * BDCC_ENG_Close and DccEngine_Init must be called again -- or
492 * alternatively, DccEngine_Reset.
493 *
494 * See Also:
495 *    BDCC_ENG_Close
496 *    DccEngine_Reset
497 *               
498 **************************************************************************/ 
499BDCC_Error BDCC_ENG_Open(
500        BDCC_ENG_Handle *phEngine, 
501        BCCGFX_WINLIB_P_Handle hWinLibHandle
502        )
503{
504    int iError;
505
506        BDCC_ENG_Handle hEngine;
507
508        BDCC_ASSERT(hWinLibHandle);
509       
510        *phEngine = hEngine = (BDCC_ENG_Handle)BKNI_Malloc( sizeof(BDCC_ENG_P_Object));
511
512        if(hEngine == NULL)
513        {
514                return BDCC_Error_eNoMemory;
515        }
516
517    BKNI_Memset(hEngine, 0, sizeof(BDCC_ENG_P_Object)) ;
518
519    hEngine->hWinLibHandle = hWinLibHandle ;
520
521    iError = BCCGFX_P_Open(&hEngine->hCCGfxHandle, hEngine->hWinLibHandle );
522
523    return iError;
524
525} /* BDCC_ENG_Open */
526
527
528BDCC_Error BDCC_ENG_Init(
529        BDCC_ENG_Handle hEngine, 
530        int iCcService,
531        BDCC_ENG_Type Type
532        )
533{
534        return BDCC_ENG_P_Init(
535                        0, 
536                        hEngine, 
537                        Type, 
538                        hEngine->hWinLibHandle, 
539                        iCcService
540                        );
541
542} /* BDCC_ENG_Init */
543
544
545/**************************************************************************               
546 * 
547 * Function:            BDCC_ENG_Close   
548 *     
549 * Inputs:                       
550 *                                      hEngine                         - init'ed previously by DccEngine_Init   
551 *   
552 * Outputs:                           
553 * 
554 * Returns:                     BDCC_Error_eSuccess or standard BDCC_Error error code     
555 *   
556 * Description:               
557 *         
558 * This function undoes the initialization of DccEngine_Init().
559 *
560 * See Also:
561 *    DccEngine_Reset
562 *    DccEngine_Init
563 *               
564 **************************************************************************/ 
565BDCC_Error BDCC_ENG_Close(BDCC_ENG_Handle hEngine)
566{
567        BDCC_ASSERT(hEngine);
568        if ( hEngine->Type == BDCC_ENG_Type_e608 )
569        {
570                BDCC_608_TranscodeClose(hEngine->h608Transcoder);
571        }
572        BDCC_Coding_P_Close(hEngine->hCodingInt);
573        BCCGFX_P_Close(hEngine->hCCGfxHandle) ;
574
575        BKNI_Free(hEngine);
576
577        return(BDCC_Error_eSuccess) ;
578       
579} /* BDCC_ENG_Close */
580
581
582/**************************************************************************               
583 * 
584 * Function:            BDCC_ENG_Reset   
585 *     
586 * Inputs:                       
587 *                                      hEngine                         - init'ed previously by BDCC_ENG_Open   
588 *                                      iCcService                              - CCx for 608 (1 to 4)
589 *                                                                                Service Number for 708 (0 to 63)
590 *                                      Type                            - 608, 708 or "NoChange"
591 *                                      Columns                         - number of columns for DTVCC grid
592 *                                                                                use 32 for 4:3 and 42 for 16:9
593 *                                      iCharCellWidth          - pixel width for char cell, must be
594 *                                                                                compatible with font/glyph design
595 *                                      iCharCellHeight         - pixel height for char cell, must be
596 *                                                                                compatible with font/glyph design
597 *   
598 * Outputs:                           
599 * 
600 * Returns:                     BDCC_Error_eSuccess or standard BDCC_Error error code     
601 *   
602 * Description:               
603 *         
604 * BDCC_ENG_Reset is logically equivalent to the sequence BDCC_ENG_Close()
605 * followed by BDCC_ENG_Open(). 
606 *
607 * Note:  This function is provided in case some advantage can be gained by
608 * consolidating _Fini and _Init.  For example, memory need not be free and
609 * re-aquired which has an effect on memory fragmentation.  Treat this function
610 * as a soft reset and the sequence _Fini and _Init as a hard reset.
611 *
612 * If Type is BDCC_ENG_Type_NoChange, then the reset is performed using the current
613 * parameters and Type, iCcService, Columns, iCharCellXxx are ignored.
614 *
615 * See Also:
616 *    BDCC_ENG_Close
617 *    BDCC_ENG_Open
618 *               
619 **************************************************************************/ 
620BDCC_Error BDCC_ENG_Reset(
621        BDCC_ENG_Handle hEngine, 
622        bool bNoChange,
623        BDCC_ENG_Type ccMode,
624        int ccService
625        )
626{
627    BDCC_Error bdccErr;
628    unsigned int OverrideMask ;
629    BDCC_ENG_OverRides Overrides ;
630
631    BSTD_UNUSED( bNoChange );
632
633    /*
634    ** Save the overrides.
635    */
636    OverrideMask = hEngine->hCodingInt->OverrideMask ;
637    Overrides = hEngine->hCodingInt->Overrides ;
638
639    /*
640    ** For now, only allow the CC service and mode to be reapplied.
641    */
642    bdccErr = BDCC_ENG_P_Init(
643                        true,                                   /* bResetOnly */
644                        hEngine, 
645                        ccMode,                             /* 608 or 708 */
646                        hEngine->hWinLibHandle,
647                        ccService
648                        );
649    /*
650    ** re-apply the overrides
651    */
652    BDCC_ENG_Override(hEngine, OverrideMask, &Overrides) ;
653
654    return( bdccErr );
655       
656}
657
658extern unsigned int ProcessCmd_GetTextCount(void);
659
660/**************************************************************************               
661 * 
662 * Function:            BDCC_ENG_Process   
663 *     
664 * Inputs:                       
665 *                                      hEngine                 - init'ed previously by DccEngine_Init 
666 *                                      pTriplets                       - ptr to buf of triplets (field,cc1,cc2)
667 *                                      NumTriplets             - count = num_bytes / 3
668 *   
669 * Outputs:                           
670 * 
671 * Returns:                     BDCC_Error_eSuccess or standard BDCC_Error error code     
672 *   
673 * Description:               
674 *         
675 * Primarily a wrapper routine around the other BDCC functions.  Provides a single
676 * entry point to simplify the interface for the application.
677 *
678 * If this function returns BDCC_Error_eBufferOverflow, it is expected that the
679 * caller will call again to DccEngine_Reset.
680 *
681 **************************************************************************/ 
682BDCC_Error BDCC_ENG_Process(
683    BDCC_ENG_Handle hEngine,
684    unsigned char * pTriplets,
685    int NumTriplets )
686{
687    static unsigned int text_count;
688    unsigned int tmp;
689    BDCC_Error bdccErr = BDCC_Error_eSuccess;
690
691    bool bTimedOut;
692
693    /*
694     ** TODO: similar checks are performed in BDCC_ENG_Process708()
695     ** and BDCC_ENG_Process608.  If this routine becomes the only entry point,
696     ** remove those checks.
697     */
698
699    if ( NULL == hEngine || NULL == pTriplets )
700    {
701        return( BDCC_Error_eNullPointer ) ;
702    }
703
704    /*
705     ** Bump the clock and drive the time dependent events.
706     ** ( flashing, scrolling, erasing windows, DELAY, FADE and WIPE )
707     */
708
709    BDCC_ENG_Periodic( hEngine );
710
711    /*
712     ** If data is availabe, call the appropriate processing rouinte.
713     */
714    if ( NumTriplets > 0 )
715        {
716                /*
717                 ** Keep track of when data was last received.
718                 ** If a "timeout", we'll need to clear the screen.
719                 */
720                tmp = ProcessCmd_GetTextCount();        /* just update time if we got text to draw */
721                if (text_count != tmp) {
722                        hEngine->uiLastDataMilliSecs = hEngine->uiCurTimeMilliSecs;
723                        hEngine->bDataReceived = true;
724                        text_count = tmp;
725                }
726
727                /*
728                 ** Based on the CC mode, direct the data to the appropriate pipe.
729                 */
730                if ( BDCC_ENG_Type_e708 == hEngine->Type )
731                {
732#if 0
733                        //RLQ
734                        unsigned int cs_count = BDCC_SRV_Get_CS_Block_Count(hEngine->iCcService708);
735#endif
736                        /*
737                         ** TODO: should we validate the data being passed by the application?
738                         */
739                        bdccErr = BDCC_ENG_Process708( hEngine, pTriplets, NumTriplets );
740#if 0
741                        if (cs_count != BDCC_SRV_Get_CS_Block_Count(hEngine->iCcService708)) {
742                                /* CS selected by the user has DCC data, switch back to it and update timeout value */
743                                hEngine->iCcService = hEngine->iCcService708;
744                                hEngine->uiLastCSMilliSecs = hEngine->uiCurTimeMilliSecs;
745                                BDCC_DBG_MSG(("CS%d service found, use it", hEngine->iCcService708)) ;
746                        }
747                        else {
748                                if ( ((hEngine->uiCurTimeMilliSecs - hEngine->uiLastCSMilliSecs) > BDCC_CS_Timeout_MSecs) && (1 != hEngine->iCcService)) {
749                                        hEngine->iCcService = 1;                /* if no CSx data for given timeout, switch to CS1 */
750                                        BDCC_DBG_MSG(("No CS%d data for given %d ms, swich to CS1", hEngine->iCcService708, BDCC_CS_Timeout_MSecs)) ;
751                                }
752                        }
753#endif
754                }
755                else if ( BDCC_ENG_Type_e608 == hEngine->Type )
756                {
757                        /*
758                         ** TODO: should we validate the data being passed by the application?
759                         */
760                        bdccErr = BDCC_ENG_Process608( hEngine, pTriplets, NumTriplets );
761
762                }
763                else
764                {
765                        return( BDCC_Error_eBadOutputType ) ;
766                }
767        }
768        else {
769                /*RLQ*/
770                /* handle DELAY command case */
771                if ( BDCC_ENG_Type_e708 == hEngine->Type ) {
772                        bdccErr = BDCC_ENG_Process708( hEngine, pTriplets, NumTriplets );
773                }
774        }
775
776        /*
777         ** Clear the screen if:
778         ** - "engineSettings.uiTimeOutMilliSecs" milliseconds have passed since CC data was received
779         ** - data has been received after the last time the screen was cleared
780         */
781
782        bTimedOut = ( hEngine->uiCurTimeMilliSecs - hEngine->uiLastDataMilliSecs > hEngine->engineSettings.uiTimeOutMilliSecs  );
783
784        if ( bTimedOut && hEngine->bDataReceived)
785        {
786                BDCC_DBG_MSG(("+++CC timeout, clear screen")) ;
787                BDCC_Coding_P_ScreenClear( hEngine->hCodingInt );
788                hEngine->bDataReceived = false;
789        }
790
791        return( bdccErr );
792
793} /* BDCC_ENG_Process608 */
794/**************************************************************************               
795 * 
796 * Function:            BDCC_ENG_Process608   
797 *     
798 * Inputs:                       
799 *                                      hEngine                         - init'ed previously by DccEngine_Init 
800 *                                      pTriplets                       - ptr to buf of triplets (field,cc1,cc2)
801 *                                      NumTriplets                     - count = num_bytes / 3
802 *   
803 * Outputs:                           
804 * 
805 * Returns:                     BDCC_Error_eSuccess or standard BDCC_Error error code     
806 *   
807 * Description:               
808 *         
809 * This function sends the CC pairs matching the supplied Field through
810 * the required processing for rendering.  This includes the 608 Transcoder.
811 *
812 * If this function returns BDCC_Error_eBufferOverflow, it is expected that the
813 * caller will call again to DccEngine_Reset.
814 *
815 **************************************************************************/ 
816BDCC_Error BDCC_ENG_Process608(
817                BDCC_ENG_Handle hEngine,
818                unsigned char * pTriplets,
819                int NumTriplets)
820{
821        BDCC_Error err ;
822
823        /*
824         * first do some validation
825         */
826        if ( NULL == hEngine   ||   pTriplets == NULL )
827        {
828                return(BDCC_Error_eNullPointer) ;
829        }
830
831        if ( NumTriplets < 0 )
832        {
833                return(BDCC_Error_eArgOutOfRange) ;
834        }
835
836        if ( hEngine->Type != BDCC_ENG_Type_e608 )
837        {
838                return(BDCC_Error_eBadOutputType) ;
839        }
840
841        /*
842         * do one pass
843         */
844        BDCC_CBUF_WritePtr(&hEngine->cbTriplets, pTriplets, NumTriplets * 3) ;
845        BDCC_608_TranscodeProcess(hEngine->h608Transcoder,&hEngine->cbTriplets, &hEngine->cbService) ;
846        BDCC_SIBuf_P_Process(hEngine->hCodingInt, &hEngine->cbService, &hEngine->cbCoding) ; 
847        BDCC_Coding_P_Process(hEngine->hCodingInt, &hEngine->cbCoding) ;
848
849        /*
850         * Now check for buffer overflow.
851         * This should never happen -- if it does
852         * either it will happen very often because
853         * the buffer sizes are not provisioned correctly
854         * or we have an errant stream.  In the first case
855         * the BDCC_ENG_P_CBUF_SIZE and BDCC_ENG_P_CBUF_RESERVE need to be
856         * corrected.  In the second case, it is appropriate to
857         * reset.  The caller of this function is expected to
858         * call again to DccEngine_Reset if this function returns
859         * BDCC_Error_eBufferOverflow.
860         */
861        err = CheckForBufferOverflow(hEngine) ;
862        return(err) ;
863
864} /* BDCC_ENG_Process608 */
865
866
867BDCC_Error WriteTripletsToCBuf(BDCC_CBUF * pCBuf, unsigned char ** ppTriplets, unsigned int * pNumTriplets)
868{
869        int TripletsThisTime = min(*pNumTriplets,pCBuf->FreeBytes/3) ;
870        int TripletsLeftover = *pNumTriplets - TripletsThisTime ;
871
872        BDCC_CBUF_WritePtr(pCBuf, *ppTriplets, TripletsThisTime * 3) ;
873        *ppTriplets += TripletsThisTime * 3 ;
874        *pNumTriplets -= TripletsThisTime ;
875
876        BDCC_DBG_MSG(("WrTToCBuf:  Trip %d  LO %d\n", TripletsThisTime, TripletsLeftover)) ;
877
878        if ( TripletsLeftover )
879                return(BDCC_Error_eWrnPause) ;
880        else
881                return(BDCC_Error_eSuccess) ;
882}
883
884
885/**************************************************************************               
886 * 
887 * Function:            BDCC_ENG_Process708   
888 *     
889 * Inputs:                       
890 *                                      hEngine                         - init'ed previously by DccEngine_Init 
891 *                                      pTriplets                       - ptr to buf of triplets (cc_type,cc1,cc2)
892 *                                      NumTriplets                     - count = num_bytes / 3
893 *   
894 * Outputs:                           
895 * 
896 * Returns:                     BDCC_Error_eSuccess or standard BDCC_Error error code     
897 *   
898 * Description:               
899 *         
900 * This function does the packet/service/coding/interpretation layers
901 * of the 708 DTVCC spec.  It filters on the Service Number provided in the
902 * previous _Init or _Reset call, as the iCcService argument.
903 *
904 * If this function returns BDCC_Error_eBufferOverflow, it is expected that the
905 * caller will call again to DccEngine_Reset.
906 *
907 **************************************************************************/ 
908#define MAX_ITER_CODING                         20
909BDCC_Error BDCC_ENG_Process708(
910                BDCC_ENG_Handle hEngine,
911                unsigned char * pTriplets,
912                int NumTriplets)
913{
914        BDCC_Error err ;
915        BDCC_Error rcA, rcB, rcC, rcD ;
916        int InnerTimes = 0 ;
917        bool newActivity;
918
919        BDCC_DBG_MSG(("%s: NumTriplets = %d", __FUNCTION__,NumTriplets));
920
921        /*
922         * first do some validation
923         */
924        if ( NULL == hEngine   ||   pTriplets == NULL )
925        {
926                return(BDCC_Error_eNullPointer) ;
927        }
928
929        if ( NumTriplets < 0 )
930        {
931                return(BDCC_Error_eArgOutOfRange) ;
932        }
933        else {
934                /* handle DELAY command case */
935                if (0 == NumTriplets) {
936                        BDCC_Update_Delay(hEngine->hCodingInt, &hEngine->cbCoding);
937                }
938        }
939
940        if ( hEngine->Type != BDCC_ENG_Type_e708 )
941        {
942                return(BDCC_Error_eBadOutputType) ;
943        }
944
945        /*
946         * do one pass
947         *
948         * The idea here is to push the input triplets all the way
949         * through the processing pipe.
950         *
951         * The obvious approach is to call each of the processing handlers
952         * once in succession, each completely consuming its input before
953         * returning.  This works fine in most of the cases, but fails for
954         * 'bursty' streams.
955         *
956         * The approach used here degenerates down to the simple approach for
957         * the normal streams (so there's really no processing overhead for
958         * most cases), but allows a processing handler to declare that its not
959         * done with its input and should be called back after its downstream
960         * handlers have gotten a chance to consume their inputs.
961         *
962         * The basic pattern used here is ...
963         *     do
964         *     {
965         *         rcA = DccAAA_Process() ;
966         *         ... other code ...
967         *     } while ( rcA == BDCC_Error_eWrnPause ) ;
968         *
969         * Stamping this pattern several times, once for each processing
970         * level, yields...
971         *     do
972         *     {
973         *         rcA = DccAAA_Process() ;
974         *         do
975         *         {
976         *             rcB = DccBBB_Process() ;
977         *             do
978         *             {
979         *                 rcC = DccCCC_Process() ;
980         *             } while ( rcC == BDCC_Error_eWrnPause ) ;
981         *         } while ( rcB == BDCC_Error_eWrnPause ) ;
982         *     } while ( rcA == BDCC_Error_eWrnPause ) ;
983         *
984         * The code below is essentially this algorithm, with an additional
985         * sanity check that we don't get stuck forever.
986         */
987        do
988        {
989                rcA = WriteTripletsToCBuf(&hEngine->cbTriplets, &pTriplets, (unsigned int *)&NumTriplets) ;
990                BDCC_DBG_MSG(("%s: NumTriplets = %d", __FUNCTION__,NumTriplets));
991                do
992                {
993                        rcB = BDCC_PKT_P_Process(&hEngine->PacketObject, &hEngine->cbTriplets, &hEngine->cbPacket) ;
994                        BDCC_DBG_MSG(("%s: hEngine->cbPacket.NumBytes = %d", __FUNCTION__,hEngine->cbPacket.NumBytes));
995                        if ( rcB == BDCC_Error_eSequence )
996                        {
997                                BDCC_DBG_MSG(("%s: Error Sequence Resetting Down Stream", __FUNCTION__));
998                                ResetDownstreamOfPacket(hEngine) ;
999                                /* track Pkt sequence number errors */
1000                                hEngine->iPktSequenceNumErr++;
1001                        }
1002
1003                        do
1004                        {
1005                                rcC = BDCC_SRV_P_Process(&hEngine->cbPacket, hEngine->iCcService, BDCC_SRV_SERVICE_ILLEGAL, &hEngine->cbService, NULL, &newActivity) ;
1006                                BDCC_DBG_MSG(("%s: hEngine->cbService.NumBytes = %d, hEngine->iCcService = %d", __FUNCTION__,hEngine->cbService.NumBytes,hEngine->iCcService));
1007                                /*
1008                                 ** Keep track of when caption data for the selected caption channel was last received.
1009                                 ** If a "timeout" (i.e. captions have been left dangling), we'll need to clear the screen.
1010                                 */
1011                                if(newActivity)
1012                                {
1013                                        hEngine->uiLastDataMilliSecs = hEngine->uiCurTimeMilliSecs;
1014                                        hEngine->bDataReceived = true;
1015                                }
1016
1017                                do
1018                                {
1019                                        rcD = BDCC_SIBuf_P_Process(hEngine->hCodingInt, &hEngine->cbService, &hEngine->cbCoding) ; 
1020#if 1
1021                                        BDCC_Coding_P_Process(hEngine->hCodingInt, &hEngine->cbCoding) ;
1022#else
1023                                        /* consume without really doing anything, useful for debug */
1024                                        hEngine->hCodingInt.SIBuf_NumCmdsWritten = 0 ;
1025                                        hEngine->hCodingInt.SIBuf_StreamBytesWritten = 0 ;
1026                                        BDCC_CBUF_Clear(&hEngine->cbCoding) ;
1027#endif
1028                                        if ( (++InnerTimes) > MAX_ITER_CODING )
1029                                        {
1030                                                BDCC_DBG_WRN(("DccEngine_Process708:  max'ed out on iterations: %d\n", InnerTimes)) ;
1031                                                /*
1032                                                 * I know, GOTOs are bad, but this seems
1033                                                 * cleaner than adding extra conditions in
1034                                                 * each of the while clauses below to do a
1035                                                 * multi-level break.
1036                                                 */
1037                                                goto StopProcessing708 ;
1038                                        }
1039                                } while ( rcD == BDCC_Error_eWrnPause ) ;
1040                        } while ( rcC == BDCC_Error_eWrnPause ) ;
1041                } while ( rcB == BDCC_Error_eWrnPause ) ;
1042        } while ( rcA == BDCC_Error_eWrnPause ) ;
1043StopProcessing708 :     
1044
1045        /*
1046         * Now check for buffer overflow.
1047         * This should never happen -- if it does
1048         * either it will happen very often because
1049         * the buffer sizes are not provisioned correctly
1050         * or we have an errant stream.  In the first case
1051         * the BDCC_ENG_P_CBUF_SIZE and BDCC_ENG_P_CBUF_RESERVE need to be
1052         * corrected.  In the second case, it is appropriate to
1053         * reset.  The caller of this function is expected to
1054         * call again to DccEngine_Reset if this function returns
1055         * BDCC_Error_eBufferOverflow.
1056         */
1057        err = CheckForBufferOverflow(hEngine) ;
1058        return(err) ;
1059
1060} /* DccEngine_Process708 */
1061
1062
1063/**************************************************************************               
1064 * 
1065 * Function:            BDCC_ENG_Override   
1066 *     
1067 * Inputs:                       
1068 *                                      hEngine                         - init'ed previously by DccEngine_Init 
1069 *                                      OverrideMask            - bitmask of overridden attributes
1070 *                                      pOverrides                      - structure of overrides
1071 *   
1072 * Outputs:                           
1073 * 
1074 * Returns:                     BDCC_Error_eSuccess or standard BDCC_Error error code     
1075 *   
1076 * Description:               
1077 *         
1078 * This function allows the caller to override some of the 708 DTVCC
1079 * interpretation attributes, such as pen size, font style and colors.
1080 *
1081 * The OverrideMask argument is a bitmask that identifies which of
1082 * structure members of *pOverrides are valid and hence overridden.  The
1083 * mask is absolute, not relative, meaning that overrides from a previous
1084 * call will be 'forgotten' if not also included in the present call.  To
1085 * undo all overrides and revert to the stream-supplied attributes, set
1086 * the OverrideMask arg to 0.
1087 *
1088 * The supported overrides are (as defined in bcmDccCoding.h):
1089 *
1090 *    UPM_PENSIZE
1091 *    UPM_FONTSTYLE
1092 *    UPM_PENFG
1093 *    UPM_PENBG
1094 *    UPM_EDGECOLOR
1095 *    UPM_EDGETYPE
1096 *
1097 **************************************************************************/ 
1098BDCC_Error BDCC_ENG_Override(
1099                BDCC_ENG_Handle hEngine,
1100                unsigned int OverrideMask, 
1101                BDCC_ENG_OverRides * pOverrides)
1102{
1103        BDCC_Error err ;
1104
1105        if ( hEngine == NULL   ||   pOverrides == NULL )
1106        {
1107                return(BDCC_Error_eNullPointer) ;
1108        }
1109
1110        err = BDCC_Coding_P_Override(hEngine->hCodingInt, OverrideMask, pOverrides) ;
1111
1112        return(err) ;
1113
1114} /* BDCC_ENG_Override */
1115
1116
1117/**************************************************************************               
1118 * 
1119 * Function:            BDCC_ENG_Periodic   
1120 *     
1121 * Inputs:                       
1122 *                                      hEngine         - init'ed previously by DccEngine_Init 
1123 *                                      usPeriod                - average us from previous call
1124 *   
1125 * Outputs:                           
1126 * 
1127 * Returns:                     BDCC_Error_eSuccess or standard BDCC_Error error code     
1128 *   
1129 * Description:               
1130 *   
1131 * This function provides the Engine API a mechanism to do sequenced
1132 * effects.  This is used for flashing and smooth scrolling.  The usPeriod
1133 * arg is set to an average value.  For example, if this is driven from a
1134 * field interrupt, it can be set to 16683 for a 59.94 Hz field rate.
1135 *
1136 **************************************************************************/ 
1137BDCC_Error BDCC_ENG_Periodic( BDCC_ENG_Handle hEngine )
1138{
1139        /*
1140         ** Call down to the interpretation layer to sample/update the time.
1141         */
1142        BCCGFX_P_TimeUpdate( hEngine->hCCGfxHandle, &(hEngine->uiCurTimeMilliSecs) );
1143
1144        /*
1145         ** call to the ccgfx library for scrolling and flashing by 2 surfaces
1146         */
1147        BCCGFX_P_Periodic(hEngine->hCCGfxHandle) ;
1148
1149        /*
1150         ** call to the interpreter for flashing by re-rendering
1151         */
1152#if FLASH_BY_RERENDER
1153        BCCGFX_INT_P_Periodic(hEngine->hCodingInt) ;
1154#endif
1155
1156        return(BDCC_Error_eSuccess) ;
1157
1158} /* BDCC_ENG_Periodic */
1159
1160
1161
1162
1163/*********************
1164 *
1165 * Support Routines
1166 *
1167 *********************/
1168
1169/**************************************************************************               
1170 * 
1171 * Function:            CheckForBufferOverflow   
1172 *     
1173 * Inputs:                       
1174 *                                      hEngine                         - init'ed previously by DccEngine_Init 
1175 *   
1176 * Outputs:                           
1177 * 
1178 * Returns:                     BDCC_Error_eSuccess or BDCC_Error_eBufferOverflow     
1179 *   
1180 * Description:               
1181 *   
1182 * This function checks the ErrorCount of each of the circular buffers.
1183 *
1184 **************************************************************************/ 
1185BDCC_Error CheckForBufferOverflow(BDCC_ENG_Handle hEngine)
1186{
1187        BDCC_DBG_MSG(("cbBufs (%4d,%4d,%4d,%4d))\n",
1188                                hEngine->cbTriplets.NumBytes,
1189                                hEngine->cbPacket.NumBytes,
1190                                hEngine->cbService.NumBytes,
1191                                hEngine->cbCoding.NumBytes)) ;
1192
1193        if ( hEngine->cbTriplets.ErrorCount )
1194        {
1195                BDCC_DBG_ERR(("ENGINE: cbTriplets overflow\n")) ;
1196                return(BDCC_Error_eBufferOverflow) ;
1197        }
1198
1199        if ( hEngine->cbPacket.ErrorCount )
1200        {
1201                BDCC_DBG_ERR(("ENGINE: cbPacket overflow\n")) ;
1202                return(BDCC_Error_eBufferOverflow) ;
1203        }
1204
1205        if ( hEngine->cbService.ErrorCount )
1206        {
1207                BDCC_DBG_ERR(("ENGINE: cbService overflow\n")) ;
1208                return(BDCC_Error_eBufferOverflow) ;
1209        }
1210
1211        if ( hEngine->cbCoding.ErrorCount )
1212        {
1213                BDCC_DBG_ERR(("ENGINE: cbCoding overflow\n")) ;
1214                return(BDCC_Error_eBufferOverflow) ;
1215        }
1216
1217        return(BDCC_Error_eSuccess) ;
1218
1219} /* CheckForBufferOverflow */
1220
1221
1222void ResetDownstreamOfPacket(BDCC_ENG_Handle hEngine)
1223{
1224        unsigned int OverrideMask ;
1225        BDCC_ENG_OverRides Overrides ;
1226
1227        BDCC_DBG_WRN(("ResetDownstreamOfPacket:  resetting\n")) ;
1228
1229        /* first save the overrides */
1230        OverrideMask = hEngine->hCodingInt->OverrideMask ;
1231        Overrides = hEngine->hCodingInt->Overrides ;
1232
1233        /*
1234         * relevant parts of BDCC_ENG_Close
1235         */
1236        BDCC_CBUF_Init(&hEngine->cbService, hEngine->BufService, sizeof(hEngine->BufService), BDCC_ENG_P_CBUF_RESERVE) ;
1237        BDCC_CBUF_Init(&hEngine->cbCoding, hEngine->BufCoding, sizeof(hEngine->BufCoding), BDCC_ENG_P_CBUF_RESERVE) ;
1238        BDCC_Coding_P_Reset(hEngine->hCodingInt) ;
1239        BCCGFX_P_Reset( hEngine->hCCGfxHandle, &hEngine->engineSettings );
1240
1241        /* re-apply the overrides */
1242        BDCC_ENG_Override(hEngine, OverrideMask, &Overrides) ;
1243
1244        BDCC_DBG_WRN(("ResetDownstreamOfPacket:  resetting - DONE\n")) ;
1245} /* ResetDownstreamOfPacket */
1246
1247BDCC_Error BDCC_ENG_LoadFont( 
1248                BDCC_ENG_Handle hEngine, 
1249                BDCC_FONT_DESCRIPTOR * pFontDesc,     
1250                int iNumToMeasure, 
1251                char * pszCharsToMeasure
1252                )
1253{
1254        BDCC_Error iError;
1255
1256        iError = BCCGFX_P_LoadFont( hEngine->hCCGfxHandle, pFontDesc, iNumToMeasure, pszCharsToMeasure );
1257
1258        return iError;
1259}
1260
1261BDCC_Error BDCC_ENG_UnloadFont( BDCC_ENG_Handle hEngine,  BDCC_FONT_DESCRIPTOR * pFontDesc )
1262{
1263        BDCC_Error iError;
1264
1265        iError = BCCGFX_P_UnloadFont( hEngine->hCCGfxHandle, pFontDesc );
1266
1267        return iError;
1268}
1269
1270BDCC_Error BDCC_ENG_AssignFont( BDCC_ENG_Handle hEngine,  BDCC_FONT_DESCRIPTOR * pFontDesc,  BDCC_PenStyle penStyle, BDCC_FontStyle fontStyle )
1271{
1272        BDCC_Error iError;
1273
1274        iError = BCCGFX_P_AssignFont( hEngine->hCCGfxHandle, pFontDesc,  penStyle, fontStyle );
1275
1276        return iError;
1277}
1278
1279uint32_t BDCC_ENG_GetPktSeqNumErrorCount(BDCC_ENG_Handle hEngine)
1280{
1281        if (hEngine)
1282                return hEngine->iPktSequenceNumErr;
1283        else
1284                return 0;
1285}
1286
1287void BDCC_ENG_ResetPktSeqNumErrorCount(BDCC_ENG_Handle hEngine)
1288{
1289        if (hEngine) {
1290                hEngine->iPktSequenceNumErr = 0;
1291        }
1292}
1293
1294
1295
Note: See TracBrowser for help on using the repository browser.