| 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 | |
|---|
| 132 | BDBG_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 | *********************/ |
|---|
| 168 | typedef 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 | |
|---|
| 245 | BDCC_Error CheckForBufferOverflow(BDCC_ENG_Handle hEngine) ; |
|---|
| 246 | void ResetDownstreamOfPacket(BDCC_ENG_Handle hEngine); |
|---|
| 247 | |
|---|
| 248 | |
|---|
| 249 | BDCC_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 | **************************************************************************/ |
|---|
| 421 | BDCC_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 | |
|---|
| 437 | BDCC_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 | |
|---|
| 451 | BDCC_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 | **************************************************************************/ |
|---|
| 499 | BDCC_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 | |
|---|
| 528 | BDCC_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 | **************************************************************************/ |
|---|
| 565 | BDCC_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 | **************************************************************************/ |
|---|
| 620 | BDCC_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 | |
|---|
| 658 | extern 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 | **************************************************************************/ |
|---|
| 682 | BDCC_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 | **************************************************************************/ |
|---|
| 816 | BDCC_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 | |
|---|
| 867 | BDCC_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 |
|---|
| 909 | BDCC_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 ) ; |
|---|
| 1043 | StopProcessing708 : |
|---|
| 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 | **************************************************************************/ |
|---|
| 1098 | BDCC_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 | **************************************************************************/ |
|---|
| 1137 | BDCC_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 | **************************************************************************/ |
|---|
| 1185 | BDCC_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 | |
|---|
| 1222 | void 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 | |
|---|
| 1247 | BDCC_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 | |
|---|
| 1261 | BDCC_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 | |
|---|
| 1270 | BDCC_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 | |
|---|
| 1279 | uint32_t BDCC_ENG_GetPktSeqNumErrorCount(BDCC_ENG_Handle hEngine) |
|---|
| 1280 | { |
|---|
| 1281 | if (hEngine) |
|---|
| 1282 | return hEngine->iPktSequenceNumErr; |
|---|
| 1283 | else |
|---|
| 1284 | return 0; |
|---|
| 1285 | } |
|---|
| 1286 | |
|---|
| 1287 | void BDCC_ENG_ResetPktSeqNumErrorCount(BDCC_ENG_Handle hEngine) |
|---|
| 1288 | { |
|---|
| 1289 | if (hEngine) { |
|---|
| 1290 | hEngine->iPktSequenceNumErr = 0; |
|---|
| 1291 | } |
|---|
| 1292 | } |
|---|
| 1293 | |
|---|
| 1294 | |
|---|
| 1295 | |
|---|