source: svn/trunk/newcon3bcm2_21bu/magnum/portinginterface/vbi/7552/bvbi_p656.c

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

first commit

  • Property svn:executable set to *
File size: 40.1 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2003-2009, 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: bvbi_p656.c $
11 * $brcm_Revision: Hydra_Software_Devel/4 $
12 * $brcm_Date: 12/21/09 7:05p $
13 *
14 * Module Description:
15 *
16 * This module provides software parsing of ITU-R 656 ancillary data packets
17 * for the VBI porting interface (BVBI).  This module is private to BVBI.
18 *
19 * Revision History:
20 *
21 * $brcm_Log: /magnum/portinginterface/vbi/7400/bvbi_p656.c $
22 *
23 * Hydra_Software_Devel/4   12/21/09 7:05p darnstein
24 * SW7550-120: Add support for SECAM variants.
25 *
26 * Hydra_Software_Devel/3   2/20/09 12:32p darnstein
27 * PR49987: fix up parsing software for SAA-7113 and SMPTE-291M ancillary
28 * data packets.
29 *
30 * Hydra_Software_Devel/2   12/3/08 7:57p darnstein
31 * PR45819: New, more modular form of most BVBI source files.
32 *
33 * Hydra_Software_Devel/15   7/16/08 1:39p darnstein
34 * PR44763: silence a compiler warning.
35 *
36 * Hydra_Software_Devel/14   9/11/07 5:18p darnstein
37 * PR25708: First release of SCTE encoder software.
38 *
39 * Hydra_Software_Devel/13   1/17/07 5:31p darnstein
40 * PR26464: correctly handle teletext output to multiple VECs
41 *
42 * Hydra_Software_Devel/12   1/2/07 4:20p darnstein
43 * PR26872: Mechanically add SECAM to all cases where PAL formats are
44 * accepted.
45 *
46 * Hydra_Software_Devel/11   3/3/06 12:49p darnstein
47 * PR18331: When BVBI_Decode_ApplyChanges() fails, roll back hardware
48 * state completely. The state was random before this fix.
49 *
50 * Hydra_Software_Devel/10   3/1/06 4:19p darnstein
51 * PR19955: For PAL teletext encoding: max lines is now 18 for both top
52 * and bottom fields. Do an "endian" swap on bit order (LSB first vs. MSB
53 * first).
54 *
55 * Hydra_Software_Devel/9   9/23/05 2:47p darnstein
56 * PR13750: Proper use of BERR_TRACE and BERR_CODEs.
57 *
58 * Hydra_Software_Devel/8   9/19/05 2:56p darnstein
59 * PR17151: Check for chip name where needed. Also, convert to new scheme
60 * for testing chip revisions (BCHP_VER).
61 *
62 * Hydra_Software_Devel/7   7/7/05 3:34p darnstein
63 * PR 16008: The default settings struct for BVBI_Open() now allows the
64 * user to choose a buffer size for capturing ancillary data packets in
65 * incoming ITU-R 656 digital video.
66 *
67 * Hydra_Software_Devel/6   7/6/05 5:55p darnstein
68 * PR 16008: Input of closed caption data in SAA7113 ancillary data
69 * packets of ITU-R 656 digital video has been confirmed. SAA7114 input
70 * almost certainly needs some debugging though.
71 *
72 * Hydra_Software_Devel/5   5/18/05 5:47p darnstein
73 * PR 11440: Progress towards ITU-R 656 input of VBI data.
74 *
75 * Hydra_Software_Devel/4   3/9/05 3:44p darnstein
76 * PR 11440: fix errors involving ITU-R 656 input and output.
77 *
78 * Hydra_Software_Devel/3   8/18/04 11:01a darnstein
79 * PR 9080: fix a minor C syntax issue discovered by Brian Lee.
80 *
81 * Hydra_Software_Devel/2   7/22/04 4:30p darnstein
82 * PR 9080: fix simple C syntax errors, found by VxWorks compiler.
83 *
84 * Hydra_Software_Devel/1   7/21/04 2:40p darnstein
85 * PR9080: Finish merging ITU-R 656 software to main branch.
86 *
87 * I656/3   7/21/04 11:34a darnstein
88 * Fix up revision history (Clearcase).
89 *
90 ***************************************************************************/
91
92#include "bstd.h"                       /* standard types */
93#include "bkni.h"                       /* Just for zeroing out DRAM */
94#include "bdbg.h"                       /* Dbglib */
95#include "bvbi.h"                       /* VBI processing, this module. */
96#include "bvbi_priv.h"      /* VBI internal data structures */
97
98BDBG_MODULE(BVBI);
99
100/* This indicates how to handle the various video standards within this
101   module.  It reflects the fact that only NTSC and PAL are supported. */
102typedef enum {
103        BVBI_P_SupportedVideo_Not=0,
104        BVBI_P_SupportedVideo_NTSC,
105        BVBI_P_SupportedVideo_PAL
106
107} BVBI_P_SupportedVideo;
108
109/* Function type for parsing the various ancillary data formats */
110typedef BERR_Code (*BVBI_P_P656_AncilParser) (
111        BFMT_VideoFmt eVideoFormat, BAVC_Polarity polarity, 
112        BVBI_P_SMPTE291Moptions* pMoptions, uint8_t* rawData, int rawLength, 
113        BVBI_SMPTE291M_Description* pktInfo, uint32_t* packetLength, 
114        uint8_t** vbiData);
115
116
117/***************************************************************************
118* Forward declarations of static (private) functions
119***************************************************************************/
120
121static BVBI_P_SupportedVideo BVBI_P_PALorNTSC (BFMT_VideoFmt eVideoFormat);
122
123static BERR_Code BVBI_P_P656_Alloc   (
124        BMEM_Handle hMem, uint8_t** i656data, size_t nBytes);
125static void      BVBI_P_P656_DeAlloc (
126        BMEM_Handle hMem, uint8_t** i656data);
127
128/* The array of parsers.  The implied index is the enum BVBI_656Fmt. */
129static BERR_Code BVBI_P_P656_SAA7113Parser (
130        BFMT_VideoFmt eVideoFormat, BAVC_Polarity polarity, 
131        BVBI_P_SMPTE291Moptions* pMoptions, uint8_t* rawData, int rawLength, 
132        BVBI_SMPTE291M_Description* pktInfo, uint32_t* packetLength, 
133        uint8_t** vbiData);
134static BERR_Code BVBI_P_P656_SAA7114Parser (
135        BFMT_VideoFmt eVideoFormat, BAVC_Polarity polarity, 
136        BVBI_P_SMPTE291Moptions* pMoptions, uint8_t* rawData, int rawLength, 
137        BVBI_SMPTE291M_Description* pktInfo, uint32_t* packetLength, 
138        uint8_t** vbiData);
139static BERR_Code BVBI_P_P656_SAA7115Parser (
140        BFMT_VideoFmt eVideoFormat, BAVC_Polarity polarity, 
141        BVBI_P_SMPTE291Moptions* pMoptions, uint8_t* rawData, int rawLength, 
142        BVBI_SMPTE291M_Description* pktInfo, uint32_t* packetLength, 
143        uint8_t** vbiData);
144static BERR_Code BVBI_P_P656_SMPTE291Parser (
145        BFMT_VideoFmt eVideoFormat, BAVC_Polarity polarity, 
146        BVBI_P_SMPTE291Moptions* pMoptions, uint8_t* rawData, int rawLength, 
147        BVBI_SMPTE291M_Description* pktInfo, uint32_t* packetLength, 
148        uint8_t** vbiData);
149static BVBI_P_P656_AncilParser AncilParserArray[BVBI_656Fmt_LAST] = {
150        BVBI_P_P656_SAA7113Parser,
151        BVBI_P_P656_SAA7113Parser,
152        BVBI_P_P656_SAA7114Parser,
153        BVBI_P_P656_SAA7114Parser,
154        BVBI_P_P656_SAA7114Parser,
155        BVBI_P_P656_SAA7114Parser,
156        BVBI_P_P656_SAA7115Parser,
157        BVBI_P_P656_SMPTE291Parser
158};
159
160/* The data movement functions for individual VBI data types */
161static uint32_t BVBI_P_P656_MoveCC  (
162        uint8_t* vbiData, BVBI_SMPTE291M_Description* pktInfo, 
163        bool isPal, uint16_t* usCCData);
164static uint32_t BVBI_P_P656_MoveWSS (
165        uint8_t* vbiData, BVBI_SMPTE291M_Description* pktInfo, 
166        bool isPal, uint16_t* usWSSData);
167static uint32_t BVBI_P_P656_MoveTT  (
168        uint8_t* vbiData, BVBI_SMPTE291M_Description* pktInfo, 
169        bool isPal, BVBI_P_TTData* TTData);
170/* TODO: VPS mover */
171
172/* Various parity bit checkers */
173static BERR_Code P_CheckE (uint8_t dataByte);
174static BERR_Code P_CheckEE (uint8_t dataByte);
175static BERR_Code P_CheckO (uint8_t dataByte);
176static BERR_Code P_CheckEE11 (uint8_t dataByte, uint8_t* payload);
177
178/* Simultaneously check for SAV/EAV control code, and 16-byte end-of-data
179   marker */
180static uint8_t* P_CheckControl (uint8_t* start, uint8_t* end);
181
182/* Check for SMPTE-291M ancillary data packet flag */
183static uint8_t* P_CheckControl_291 (uint8_t* start, uint8_t* end);
184
185/* (even) parity of numbers between 0 and 255 */
186static const unsigned char P_bitParity[256] = {
187        0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 
188        1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 
189        1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 
190        0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 
191        1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 
192        0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 
193        0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 
194        1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 
195        1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 
196        0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 
197        0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 
198        1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 
199        0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 
200        1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 
201        1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 
202        0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0
203};
204
205/***************************************************************************
206* Implementation of "BVBI_" API functions
207***************************************************************************/
208
209
210/***************************************************************************
211* Implementation of supporting VBI_DEC functions that are not in API
212***************************************************************************/
213
214/***************************************************************************
215 *
216 */
217BERR_Code BVBI_P_P656_Init ( BVBI_P_Decode_Handle* pVbi_Dec )
218{
219        BVBI_P_Handle* pVbi = pVbi_Dec->pVbi;
220        BERR_Code eErr = BERR_SUCCESS;
221
222        /* Allocate space for double buffering ITU-R 656 ancillary data */
223        if ((eErr = BERR_TRACE (BVBI_P_P656_Alloc (
224                pVbi->hMem, &pVbi_Dec->top656Data, pVbi->in656bufferSize))) != 
225                        BERR_SUCCESS)
226        {
227                return eErr;
228        }
229        if ((eErr = BERR_TRACE (BVBI_P_P656_Alloc (
230                pVbi->hMem, &pVbi_Dec->bot656Data, pVbi->in656bufferSize))) != 
231                        BERR_SUCCESS)
232        {
233                return eErr;
234        }
235
236        /* Zero out the data */
237        BKNI_Memset (pVbi_Dec->top656Data, 0, pVbi->in656bufferSize);
238        BKNI_Memset (pVbi_Dec->bot656Data, 0, pVbi->in656bufferSize);
239
240        return eErr;
241}
242
243/***************************************************************************
244 *
245 */
246void BVBI_P_P656_DeInit ( BVBI_P_Decode_Handle* pVbi_Dec )
247{
248        BVBI_P_Handle* pVbi = pVbi_Dec->pVbi;
249
250        /* Release space for double buffering ITU-R 656 ancillary data */
251        BVBI_P_P656_DeAlloc (pVbi->hMem, &pVbi_Dec->top656Data);
252        BVBI_P_P656_DeAlloc (pVbi->hMem, &pVbi_Dec->bot656Data);
253}
254
255
256/***************************************************************************
257 *
258 */
259BERR_Code BVBI_P_P656_Process_Data_isr (
260        BAVC_Polarity polarity,
261        BVBI_P_Decode_Handle* pVbi_Dec,
262        BVBI_P_Field_Handle* pVbi_Fld)
263{
264        uint8_t* rawData;
265        uint8_t* currData;
266        uint8_t* vbiData;
267        int currLength;
268        int lineWidth;
269        uint32_t packetLength;
270        uint32_t whatActive;
271        bool isPal;
272        BVBI_P_P656_AncilParser ancilParser;
273        BVBI_SMPTE291M_Description pktInfo;
274        BVBI_P_TTData* ttData;
275        uint32_t ulErrInfo = 0x0;
276
277        BDBG_ENTER (BVBI_P_P656_Process_Data_isr);
278
279        /* Determine where data is coming from */
280        switch (polarity)
281        {
282        case BAVC_Polarity_eTopField:
283                rawData = pVbi_Dec->top656Data;
284                break;
285        case BAVC_Polarity_eBotField:
286                rawData = pVbi_Dec->bot656Data;
287                break;
288        default:
289                BDBG_LEAVE (BVBI_P_P656_Process_Data_isr);
290                return BERR_TRACE (BERR_INVALID_PARAMETER);
291                break;
292        }
293        currData = rawData;
294        currLength = pVbi_Dec->pVbi->in656bufferSize;
295
296        /* Determine if PAL or NTSC (for teletext, mostly). */
297        switch (BVBI_P_PALorNTSC (pVbi_Dec->curr.eVideoFormat))
298        {
299    case BVBI_P_SupportedVideo_NTSC:
300                isPal = false;
301                lineWidth = 34;
302                break;
303
304    case BVBI_P_SupportedVideo_PAL:
305                isPal = true;
306                lineWidth = 43;
307                break;
308
309        default:
310                lineWidth = 0;
311                isPal = false;
312                break;
313        }
314
315        /* Initialize teletext data in field handle, if present. */
316        BVBI_P_LCOP_WRITE_isr (
317                pVbi_Fld, TTDataO, &pVbi_Dec->pVbi->ttFreelist, clink);
318        ttData = BVBI_P_LCOP_GET_isr (pVbi_Fld, TTDataO);
319        ttData->ucLineSize = lineWidth;
320        ttData->ucLines = 0;
321        if (ttData->ucDataSize > 0)
322                *(uint32_t*)(ttData->pucData) = 0x00000000;
323
324        /* Determine which ancillary data parser to use */
325        ancilParser = AncilParserArray[pVbi_Dec->curr.e656Format];
326
327        /* Convenience */
328        whatActive = pVbi_Dec->curr.ulActive_Standards;
329
330        /* Loop over captured ancillary data packets */
331        while (currLength > 0)
332        {
333                if ((*ancilParser) (pVbi_Dec->curr.eVideoFormat, polarity, 
334                                                        &(pVbi_Dec->curr.SMPTE291Moptions), currData, 
335                                                        currLength, &pktInfo, &packetLength, &vbiData)
336                        == BERR_SUCCESS)
337                {
338                        /* Determine which VBI standard to parse */
339                        if ((whatActive & BVBI_P_SELECT_CC) &&
340                                ((pktInfo.vbiType == BVBI_656_VbiType_EuroCC) ||
341                                 (pktInfo.vbiType == BVBI_656_VbiType_USCC  )))
342                        {
343                                ulErrInfo = BVBI_P_P656_MoveCC (
344                                        vbiData, &pktInfo, isPal, &pVbi_Fld->usCCData);
345                                if ((ulErrInfo & BVBI_LINE_ERROR_CC_NODATA) == 0)
346                                        pVbi_Fld->ulWhichPresent |= BVBI_P_SELECT_CC;
347                                pVbi_Fld->ulErrInfo |= ulErrInfo;
348                        }
349                        if ((whatActive & BVBI_P_SELECT_WSS) &&
350                                (pktInfo.vbiType == BVBI_656_VbiType_WSS))
351                        {
352                                ulErrInfo = BVBI_P_P656_MoveWSS (
353                                        vbiData, &pktInfo, isPal, &pVbi_Fld->usWSSData);
354                                if ((ulErrInfo & BVBI_LINE_ERROR_WSS_NODATA) == 0)
355                                        pVbi_Fld->ulWhichPresent |= BVBI_P_SELECT_WSS;
356                                pVbi_Fld->ulErrInfo |= ulErrInfo;
357                        }
358                        if ((whatActive & BVBI_P_SELECT_TT) &&
359                                ((pktInfo.vbiType == BVBI_656_VbiType_TT   ) ||
360                                 (pktInfo.vbiType == BVBI_656_VbiType_NABTS)))
361                        {
362                                ulErrInfo = BVBI_P_P656_MoveTT (
363                                        vbiData, &pktInfo, isPal, ttData);
364                                if ((ulErrInfo & BVBI_LINE_ERROR_TELETEXT_NODATA) == 0)
365                                        pVbi_Fld->ulWhichPresent |= BVBI_P_SELECT_TT;
366                                pVbi_Fld->ulErrInfo |= ulErrInfo;
367                        }
368                        /* TODO: VPS decoding. */
369                }
370
371                /* Advance to next ancillary data packet */
372                currData   += packetLength;
373                currLength -= packetLength;
374                if (currLength < 5)
375                        break;
376        }
377
378        BDBG_LEAVE (BVBI_P_P656_Process_Data_isr);
379        return BERR_SUCCESS;
380}
381
382
383/***************************************************************************
384 *
385 */
386uint8_t BVBI_P_p656_SetEEbits (uint8_t arg)
387{
388        uint8_t retval = arg & 0x3F;
389        uint8_t parityBit = P_bitParity[retval];
390        uint8_t oppositeBit = !parityBit;
391        return retval | (parityBit << 6) | (oppositeBit << 7);
392}
393
394/***************************************************************************
395* Static (private) functions
396***************************************************************************/
397
398
399/***************************************************************************
400 *
401 */
402static BERR_Code BVBI_P_P656_Alloc (
403        BMEM_Handle hMem, uint8_t** i656data, size_t nBytes)
404{
405        *i656data = 
406                (uint8_t*)(BMEM_AllocAligned (
407                        hMem,
408                        nBytes,
409                        5,
410                        0));
411        if (!(*i656data))
412        {
413                return BERR_TRACE(BERR_OUT_OF_SYSTEM_MEMORY);
414        }
415
416        return BERR_SUCCESS;
417}
418
419/***************************************************************************
420 *
421 */
422static void BVBI_P_P656_DeAlloc (
423        BMEM_Handle hMem, uint8_t** i656data)
424{
425        BMEM_Free (hMem, *i656data);
426        *i656data = 0;
427}
428
429
430/***************************************************************************
431 *
432 */
433static BERR_Code BVBI_P_P656_SAA7113Parser (
434        BFMT_VideoFmt eVideoFormat, BAVC_Polarity polarity, 
435        BVBI_P_SMPTE291Moptions* pMoptions, uint8_t* rawData, int rawLength, 
436        BVBI_SMPTE291M_Description* pktInfo, uint32_t* packetLength, 
437        uint8_t** vbiData)
438{
439        uint16_t msn16, lsn16;
440        uint8_t vbiType;
441        int nBytes;
442        BAVC_Polarity parsedPolarity;
443        uint8_t* currData = rawData;
444        uint8_t* endData  = rawData + rawLength;
445        uint8_t* outData  = rawData;
446        BERR_Code eErr = BERR_SUCCESS;
447
448        /* This is part of the SAA7113 syntax */
449        static uint8_t payloadSize[16] = {
450                /*  0: -------------------- */   0,
451                /*  1: Euro. Closed Caption */   2,
452                /*  2: -------------------- */   0,
453                /*  3: WSS                  */   3,
454                /*  4: WST (not supported)  */  34,
455                /*  5: U.S. Closed Caption  */   2,
456                /*  6: -------------------- */   0,
457                /*  7: -------------------- */   0,
458                /*  8: Euro. teletext       */  42,
459                /*  9: -------------------- */   0,
460                /* 10: -------------------- */   0,
461                /* 11: -------------------- */   0,
462                /* 12: NABTS                */  34,
463                /* 13: -------------------- */   0,
464                /* 14: -------------------- */   0,
465                /* 15: -------------------- */   0
466        };
467
468        /* This translates from SAA7113 syntax to BVBI private enum */
469        static BVBI_656_VbiType payloadType[16] = {
470                /*  0: -------------------- */   BVBI_656_VbiType_None,
471                /*  1: Euro. Closed Caption */   BVBI_656_VbiType_EuroCC,
472                /*  2: -------------------- */   BVBI_656_VbiType_None,
473                /*  3: WSS                  */   BVBI_656_VbiType_WSS,
474                /*  4: WST (not supported)  */   BVBI_656_VbiType_None,
475                /*  5: U.S. Closed Caption  */   BVBI_656_VbiType_USCC,
476                /*  6: -------------------- */   BVBI_656_VbiType_None,
477                /*  7: -------------------- */   BVBI_656_VbiType_None,
478                /*  8: Euro. teletext       */   BVBI_656_VbiType_TT,
479                /*  9: -------------------- */   BVBI_656_VbiType_None,
480                /* 10: -------------------- */   BVBI_656_VbiType_None,
481                /* 11: -------------------- */   BVBI_656_VbiType_None,
482                /* 12: NABTS                */   BVBI_656_VbiType_NABTS,
483                /* 13: -------------------- */   BVBI_656_VbiType_None,
484                /* 14: -------------------- */   BVBI_656_VbiType_None,
485                /* 15: -------------------- */   BVBI_656_VbiType_None
486        };
487
488        /* This translates from SAA7113 syntax to another BVBI private enum */
489        static BVBI_P_SupportedVideo videoType[16] = {
490                /*  0: -------------------- */   BVBI_P_SupportedVideo_Not,
491                /*  1: Euro. Closed Caption */   BVBI_P_SupportedVideo_PAL,
492                /*  2: -------------------- */   BVBI_P_SupportedVideo_Not,
493                /*  3: WSS                  */   BVBI_P_SupportedVideo_PAL,
494                /*  4: WST (not supported)  */   BVBI_P_SupportedVideo_Not,
495                /*  5: U.S. Closed Caption  */   BVBI_P_SupportedVideo_NTSC,
496                /*  6: -------------------- */   BVBI_P_SupportedVideo_Not,
497                /*  7: -------------------- */   BVBI_P_SupportedVideo_Not,
498                /*  8: Euro. teletext       */   BVBI_P_SupportedVideo_PAL,
499                /*  9: -------------------- */   BVBI_P_SupportedVideo_Not,
500                /* 10: -------------------- */   BVBI_P_SupportedVideo_Not,
501                /* 11: -------------------- */   BVBI_P_SupportedVideo_Not,
502                /* 12: NABTS                */   BVBI_P_SupportedVideo_NTSC,
503                /* 13: -------------------- */   BVBI_P_SupportedVideo_Not,
504                /* 14: -------------------- */   BVBI_P_SupportedVideo_Not,
505                /* 15: -------------------- */   BVBI_P_SupportedVideo_Not
506        };
507
508        BSTD_UNUSED (pMoptions);
509
510        /* Will overwrite input data */
511        *vbiData = rawData;
512
513        /* Search for three byte header or end-of-data */
514        currData = P_CheckControl (currData, endData);
515
516        /* Bail out if no data found */
517        if ((currData + 5) >= endData)
518        {
519                *packetLength = rawLength;
520                eErr = BVBI_ERR_656_PARSE;
521                goto ErrorTransfer_BVBI_P_P656_SAA7113Parser;
522        }
523
524        /* TODO: parse the SAV byte */
525        ++currData;
526
527        /* Check the SOURCE ID byte for corruption */
528        if (P_CheckEE (*currData) != BERR_SUCCESS)
529        {
530                *packetLength = currData - rawData;
531                eErr = BVBI_ERR_656_PARSE;
532                goto ErrorTransfer_BVBI_P_P656_SAA7113Parser;
533        }
534        ++currData;
535
536        /* Dig out and ignore the DWORD COUNT */
537        if (P_CheckEE (*currData) != BERR_SUCCESS)
538        {
539                *packetLength = currData - rawData;
540                eErr = BVBI_ERR_656_PARSE;
541                goto ErrorTransfer_BVBI_P_P656_SAA7113Parser;
542        }
543        ++currData;
544
545        /* Dig out (part of) line count and field indicator,
546           checking for corruption. */
547        if (P_CheckO (*currData) != BERR_SUCCESS)
548        {
549                *packetLength = currData - rawData;
550                eErr = BVBI_ERR_656_PARSE;
551                goto ErrorTransfer_BVBI_P_P656_SAA7113Parser;
552        }
553        parsedPolarity = 
554                (((*currData) & 0x40) == 0) ? 
555                        BAVC_Polarity_eTopField : BAVC_Polarity_eBotField;
556        pktInfo->polarity = parsedPolarity;
557        msn16 = (*currData) & 0x3f;
558        ++currData;
559
560        /* Insist on agreement for field parity */
561        if (parsedPolarity != polarity)
562        {
563                /* Programming note: Broadcom ANCI_656 core does not
564                   provide parity bit. */
565                *packetLength = currData - rawData;
566                eErr = BVBI_ERR_656_PARSE; 
567                goto ErrorTransfer_BVBI_P_P656_SAA7113Parser;
568        }
569
570        /* Dig out (part of) line count and VBI type indicator,
571           checking for corruption. */
572        if (P_CheckO (*currData) != BERR_SUCCESS)
573        {
574                *packetLength = currData - rawData;
575                eErr = BVBI_ERR_656_PARSE;
576                goto ErrorTransfer_BVBI_P_P656_SAA7113Parser;
577        }
578        lsn16 = ((*currData) & 0x70) >> 4;
579        pktInfo->lineNumber = (msn16 << 3) | lsn16;
580        vbiType = (*currData) & 0x0F;
581        ++currData;
582
583        /* Check for unsupported VBI type, otherwise return info to caller. */
584        if (payloadType[vbiType] == BVBI_656_VbiType_None)
585        {
586                *packetLength = currData - rawData;
587                eErr = BVBI_ERR_656_PARSE;
588                goto ErrorTransfer_BVBI_P_P656_SAA7113Parser;
589        }
590        pktInfo->vbiType = payloadType[vbiType];
591
592        /* Check for conflict with video standard (PAL vs NTSC) */
593        if (videoType[vbiType] != BVBI_P_PALorNTSC (eVideoFormat))
594        {
595                *packetLength = currData - rawData;
596                eErr = BVBI_ERR_656_PARSE;
597                goto ErrorTransfer_BVBI_P_P656_SAA7113Parser;
598        }
599
600        /* Compute the "payload" size */
601        nBytes = payloadSize[vbiType];
602        if (nBytes == 0)
603        {
604                *packetLength = currData - rawData;
605                eErr = BVBI_ERR_656_PARSE;
606                goto ErrorTransfer_BVBI_P_P656_SAA7113Parser;
607        }
608        if (currData + 2 * nBytes > endData)
609        {
610                *packetLength = currData - rawData;
611                eErr = BVBI_ERR_656_PARSE;
612                goto ErrorTransfer_BVBI_P_P656_SAA7113Parser;
613        }
614
615        /* Dig out the "payload" */
616        while (nBytes-- > 0)
617        {
618                uint8_t msn = 0x0;
619                uint8_t lsn = 0x0;
620                if (P_CheckEE11 (*currData, &lsn) != BERR_SUCCESS)
621                {
622                        *packetLength = currData - rawData;
623                        eErr = BVBI_ERR_656_PARSE;
624                        goto ErrorTransfer_BVBI_P_P656_SAA7113Parser;
625                }
626                ++currData;
627                if (P_CheckEE11 (*currData, &msn) != BERR_SUCCESS)
628                {
629                        *packetLength = currData - rawData;
630                        eErr = BVBI_ERR_656_PARSE;
631                        goto ErrorTransfer_BVBI_P_P656_SAA7113Parser;
632                }
633                ++currData;
634                *outData++ = (msn << 4) | lsn;
635        }
636
637        /* "Parse" the packet suffix */
638        if (currData + 4 > endData)
639        {
640                *packetLength = currData - rawData;
641                eErr = BVBI_ERR_656_PARSE;
642                goto ErrorTransfer_BVBI_P_P656_SAA7113Parser;
643        }
644        /* TODO: parse the EAV byte */
645        if ((currData[0] != 0xFF) || (currData[1] != 0x00) || 
646            (currData[2] != 0x00))
647        {
648                *packetLength = currData - rawData;
649                eErr = BVBI_ERR_656_PARSE;
650                goto ErrorTransfer_BVBI_P_P656_SAA7113Parser;
651        }
652        currData += 4;
653
654        /* Packet parsing complete! */
655        *packetLength = currData - rawData;
656
657ErrorTransfer_BVBI_P_P656_SAA7113Parser:
658        return eErr;
659
660}
661
662
663/***************************************************************************
664 *
665 */
666static BERR_Code BVBI_P_P656_SAA7114Parser (
667        BFMT_VideoFmt eVideoFormat, BAVC_Polarity polarity, 
668        BVBI_P_SMPTE291Moptions* pMoptions, uint8_t* rawData, int rawLength, 
669        BVBI_SMPTE291M_Description* pktInfo, uint32_t* packetLength, 
670        uint8_t** vbiData)
671{
672        uint16_t msn16, lsn16;
673        uint8_t vbiType;
674        uint8_t checksum;
675        int nBytes;
676        int dataByteCounter;
677        BAVC_Polarity parsedPolarity;
678        uint8_t* currData = rawData;
679        uint8_t* endData  = rawData + rawLength;
680        uint8_t* outData  = rawData;
681
682        /* This is part of the SAA7114 syntax */
683        static uint8_t payloadSize[16] = {
684                /*  0: -------------------- */   0,
685                /*  1: Euro. Closed Caption */   2,
686                /*  2: VPS (TODO)           */   0,
687                /*  3: WSS                  */   3,
688                /*  4: NABTS; fr. code x27  */  34,
689                /*  5: U.S. Closed Caption  */   2,
690                /*  6: -------------------- */   0,
691                /*  7: -------------------- */   0,
692                /*  8: WST (not supported)  */  42,
693                /*  9: -------------------- */   0,
694                /* 10: -------------------- */   0,
695                /* 11: -------------------- */   0,
696                /* 12: NABTS                */  34,
697                /* 13: -------------------- */   0,
698                /* 14: -------------------- */   0,
699                /* 15: -------------------- */   0
700        };
701
702        /* This translates from SAA7114 syntax to BVBI private enum */
703        static BVBI_656_VbiType payloadType[16] = {
704                /*  0: -------------------- */   BVBI_656_VbiType_None,
705                /*  1: Euro. Closed Caption */   BVBI_656_VbiType_EuroCC,
706                /*  2: -------------------- */   BVBI_656_VbiType_None,
707                /*  3: WSS                  */   BVBI_656_VbiType_WSS,
708                /*  4: WST (not supported)  */   BVBI_656_VbiType_None,
709                /*  5: U.S. Closed Caption  */   BVBI_656_VbiType_USCC,
710                /*  6: -------------------- */   BVBI_656_VbiType_None,
711                /*  7: -------------------- */   BVBI_656_VbiType_None,
712                /*  8: Euro. teletext       */   BVBI_656_VbiType_TT,
713                /*  9: -------------------- */   BVBI_656_VbiType_None,
714                /* 10: -------------------- */   BVBI_656_VbiType_None,
715                /* 11: -------------------- */   BVBI_656_VbiType_None,
716                /* 12: NABTS                */   BVBI_656_VbiType_NABTS,
717                /* 13: -------------------- */   BVBI_656_VbiType_None,
718                /* 14: -------------------- */   BVBI_656_VbiType_None,
719                /* 15: -------------------- */   BVBI_656_VbiType_None
720        };
721
722        /* This translates from SAA7114 syntax to another BVBI private enum */
723        static BVBI_P_SupportedVideo videoType[16] = {
724                /*  0: -------------------- */   BVBI_P_SupportedVideo_Not,
725                /*  1: Euro. Closed Caption */   BVBI_P_SupportedVideo_PAL,
726                /*  2: -------------------- */   BVBI_P_SupportedVideo_Not,
727                /*  3: WSS                  */   BVBI_P_SupportedVideo_PAL,
728                /*  4: WST (not supported)  */   BVBI_P_SupportedVideo_Not,
729                /*  5: U.S. Closed Caption  */   BVBI_P_SupportedVideo_NTSC,
730                /*  6: -------------------- */   BVBI_P_SupportedVideo_Not,
731                /*  7: -------------------- */   BVBI_P_SupportedVideo_Not,
732                /*  8: Euro. teletext       */   BVBI_P_SupportedVideo_PAL,
733                /*  9: -------------------- */   BVBI_P_SupportedVideo_Not,
734                /* 10: -------------------- */   BVBI_P_SupportedVideo_Not,
735                /* 11: -------------------- */   BVBI_P_SupportedVideo_Not,
736                /* 12: NABTS                */   BVBI_P_SupportedVideo_NTSC,
737                /* 13: -------------------- */   BVBI_P_SupportedVideo_Not,
738                /* 14: -------------------- */   BVBI_P_SupportedVideo_Not,
739                /* 15: -------------------- */   BVBI_P_SupportedVideo_Not
740        };
741
742        BSTD_UNUSED (pMoptions);
743
744        /* Will overwrite input data */
745        *vbiData = rawData;
746
747        /* Search for three byte header or end-of-data */
748        currData = P_CheckControl (currData, endData);
749
750        /* Bail out if no data found */
751        if ((currData + 5) >= endData)
752        {
753                *packetLength = rawLength;
754                return BERR_TRACE (BVBI_ERR_656_PARSE);
755        }
756
757
758        /* Checksum begins with SAV byte */
759        /* TODO: Parse the SAV byte */
760        checksum = *currData;
761        ++currData;
762
763        /* Check the SOURCE ID byte for corruption */
764        if (P_CheckEE (*currData) != BERR_SUCCESS)
765        {
766                *packetLength = currData - rawData;
767                return BERR_TRACE (BVBI_ERR_656_PARSE);
768        }
769        checksum += (*currData);
770        ++currData;
771
772        /* Dig out the DWORD COUNT */
773        if (P_CheckEE (*currData) != BERR_SUCCESS)
774        {
775                *packetLength = currData - rawData;
776                return BERR_TRACE (BVBI_ERR_656_PARSE);
777        }
778        dataByteCounter = 4 * ((*currData) & 0x3F);
779        checksum += (*currData);
780        ++currData;
781
782        /* Dig out (part of) line count and field indicator,
783           checking for corruption. */
784        if (P_CheckO (*currData) != BERR_SUCCESS)
785        {
786                *packetLength = currData - rawData;
787                return BERR_TRACE (BVBI_ERR_656_PARSE);
788        }
789        checksum += (*currData);
790        parsedPolarity = 
791                (((*currData) & 0x40) == 0) ?
792                        BAVC_Polarity_eTopField : BAVC_Polarity_eBotField;
793        pktInfo->polarity = parsedPolarity;
794        msn16 = (*currData) & 0x3f;
795        ++currData;
796        --dataByteCounter;
797
798        /* Insist on agreement for field parity */
799        if (parsedPolarity != polarity)
800        {
801                *packetLength = currData - rawData;
802                return BERR_TRACE (BVBI_ERR_656_PARSE);
803        }
804
805        /* Dig out (part of) line count and VBI type indicator,
806           checking for corruption. */
807        if (P_CheckO (*currData) != BERR_SUCCESS)
808        {
809                *packetLength = currData - rawData;
810                return BERR_TRACE (BVBI_ERR_656_PARSE);
811        }
812        checksum += (*currData);
813        --dataByteCounter;
814        lsn16 = ((*currData) & 0x70) >> 4;
815        pktInfo->lineNumber = (msn16 << 3) | lsn16;
816        vbiType = (*currData) & 0x0F;
817        ++currData;
818
819        /* Check for unsupported VBI type, otherwise return info to caller. */
820        if (payloadType[vbiType] == BVBI_656_VbiType_None)
821        {
822                *packetLength = currData - rawData;
823                return BERR_TRACE (BVBI_ERR_656_PARSE);
824        }
825        pktInfo->vbiType = payloadType[vbiType];
826
827        /* Check for conflict with video standard (PAL vs NTSC) */
828        if (videoType[vbiType] != BVBI_P_PALorNTSC (eVideoFormat))
829        {
830                *packetLength = currData - rawData;
831                return BERR_TRACE (BVBI_ERR_656_PARSE);
832        }
833
834        /* Compute the "payload" size */
835        nBytes = payloadSize[vbiType];
836        if (nBytes == 0)
837        {
838                *packetLength = currData - rawData;
839                return BERR_TRACE (BVBI_ERR_656_PARSE);
840        }
841        if (currData + 2 * nBytes > endData)
842        {
843                *packetLength = currData - rawData;
844                return BERR_TRACE (BVBI_ERR_656_PARSE);
845        }
846
847        /* Dig out the "payload" */
848        while (nBytes-- > 0)
849        {
850                *outData++ = *currData;
851                checksum += (*currData);
852                --dataByteCounter;
853                ++currData;
854        }
855
856        /* Count the fill bytes */
857        while (dataByteCounter-- > 0)
858        {
859                checksum += (*currData);
860                ++currData;
861        }
862
863        /* Verify the checksum byte */
864        if (P_CheckE (*currData) != BERR_SUCCESS)
865        {
866                *packetLength = currData - rawData;
867                return BERR_TRACE (BVBI_ERR_656_PARSE);
868        }
869        if ( ((*currData) & 0x7F) != (checksum & 0x7F) )
870        {
871                *packetLength = currData - rawData;
872                return BERR_TRACE (BVBI_ERR_656_PARSE);
873        }
874
875        /* Parse out the BYTE COUNT byte */
876        if (P_CheckO (*currData) != BERR_SUCCESS)
877        {
878                *packetLength = currData - rawData;
879                return BERR_TRACE (BVBI_ERR_656_PARSE);
880        }
881        /* TODO: interpret the BYTE COUNT byte */
882        ++currData;
883
884        /* "Parse" the packet suffix */
885        if (currData + 4 > endData)
886        {
887                *packetLength = currData - rawData;
888                return BERR_TRACE (BVBI_ERR_656_PARSE);
889        }
890        /* TODO: parse the EAV byte */
891        if ((currData[0] != 0xFF) || (currData[1] != 0x00) || 
892            (currData[2] != 0x00))
893        {
894                *packetLength = currData - rawData;
895                return BERR_TRACE (BVBI_ERR_656_PARSE);
896        }
897        currData += 4;
898
899        /* Packet parsing complete! */
900        *packetLength = currData - rawData;
901        return BERR_SUCCESS;
902}
903
904
905/***************************************************************************
906 *
907 */
908static BERR_Code BVBI_P_P656_SAA7115Parser (
909        BFMT_VideoFmt eVideoFormat, BAVC_Polarity polarity,
910        BVBI_P_SMPTE291Moptions* pMoptions, uint8_t* rawData, int rawLength, 
911        BVBI_SMPTE291M_Description* pktInfo, uint32_t* packetLength, 
912        uint8_t** vbiData)
913{
914        /* TODO: check for differences between SAA7114 and SAA 7115 */
915        return 
916                BERR_TRACE (BVBI_P_P656_SAA7114Parser (
917                        eVideoFormat, polarity, pMoptions, rawData, rawLength, pktInfo, 
918                        packetLength, vbiData));
919}
920
921
922/***************************************************************************
923 *
924 */
925static BERR_Code BVBI_P_P656_SMPTE291Parser (
926        BFMT_VideoFmt eVideoFormat, BAVC_Polarity polarity, 
927        BVBI_P_SMPTE291Moptions* pMoptions, uint8_t* rawData, int rawLength, 
928        BVBI_SMPTE291M_Description* pktInfo, uint32_t* packetLength, 
929        uint8_t** vbiData)
930{
931        uint8_t checksum;
932        uint8_t data_id;
933        uint8_t second_id = 0x0;
934        uint8_t data_count;
935        int dataByteCounter;
936        uint8_t* packet;
937        uint8_t* currData = rawData;
938        uint8_t* endData  = rawData + rawLength;
939
940        /* Search for header */
941        if (pMoptions->bLongHeader)
942        {
943                /* Search for three byte header or end-of-data */
944                currData = P_CheckControl_291 (currData, endData);
945        }
946        else
947        {
948                while (currData < endData)
949                {
950                        if (currData[0] == 0xFF)
951                        {
952                                break;
953                        }
954                        ++currData;
955                }
956                ++currData;
957        }
958
959        /* Bail out if no data found */
960        if ((currData + 5) >= endData)
961        {
962                *packetLength = rawLength;
963                return BERR_TRACE (BVBI_ERR_656_PARSE);
964        }
965
966        /* Checksum begins with DATA ID byte */
967        if (P_CheckEE (*currData) != BERR_SUCCESS)
968        {
969                *packetLength = rawLength;
970                return BERR_TRACE (BVBI_ERR_656_PARSE);
971        }
972        data_id = (*currData) & 0x3F;
973        if (data_id == 0x0)
974        {
975                *packetLength = rawLength;
976                return BERR_TRACE (BVBI_ERR_656_PARSE);
977        }
978        checksum = *currData;
979        ++currData;
980
981        /* Second Data ID or block number: */
982        /* Check the SECOND ID byte for corruption */
983        if (P_CheckEE (*currData) != BERR_SUCCESS)
984        {
985                /* Programming note: SDID seems to be always "1"
986                   coming from Broadcom's ANCI_656_656 core. */
987                *packetLength = rawLength;
988                return BERR_TRACE (BVBI_ERR_656_PARSE);
989        }
990        second_id = (*currData) & 0x3F;
991        checksum += (*currData);
992        ++currData;
993
994        /* Dig out the DWORD COUNT */
995        if (pMoptions->bBrokenDataCount)
996        {
997                data_count = *currData;
998                dataByteCounter = data_count;
999        }
1000        else
1001        {
1002                if (P_CheckEE (*currData) != BERR_SUCCESS)
1003                {
1004                        /* Programming note: Broadcom's ANCI656_656
1005                           core doesn't add parity bits */
1006                        *packetLength = rawLength;
1007                        return BERR_TRACE (BVBI_ERR_656_PARSE);
1008                }
1009                data_count = (*currData) & 0x3F;
1010                dataByteCounter = 4 * data_count;
1011        }
1012        checksum += (*currData);
1013        ++currData;
1014
1015        /* This is needed to avoid infinite loop in calling function */
1016        if (dataByteCounter == 0)
1017        {
1018                *packetLength = rawLength;
1019                return BERR_TRACE (BVBI_ERR_656_PARSE);
1020        }
1021
1022        /* Here is the raw data to pass to the callback function */
1023        packet = currData;
1024
1025        /* Checksum the "payload" */
1026        while (dataByteCounter > 0)
1027        {
1028                checksum += (*currData);
1029                ++currData;
1030                --dataByteCounter;
1031        }
1032
1033        /* Verify the checksum byte */
1034        if ( (*currData) != checksum )
1035        {
1036                *packetLength = rawLength;
1037                return BERR_TRACE (BVBI_ERR_656_PARSE);
1038        }
1039
1040        /* The user callback does the rest */
1041        if (!(pMoptions->bBrokenDataCount))
1042                data_count *= 4;
1043        return BERR_TRACE ((pMoptions->fParseCb) (
1044                pMoptions->fParseCbArg0, 
1045                eVideoFormat,
1046                polarity,
1047                data_id,
1048                second_id,
1049                data_count,
1050                packet,
1051                vbiData,
1052                pktInfo));
1053}
1054
1055
1056/***************************************************************************
1057 *
1058 */
1059BERR_Code BVBI_Decode_656_SMPTE291MbrcmCb_isr (
1060        void* arg0, 
1061        BFMT_VideoFmt eVideoFormat,
1062        BAVC_Polarity polarity,
1063        uint8_t data_id, 
1064        uint8_t second_id, 
1065        uint8_t data_count, 
1066        uint8_t* packet, 
1067    uint8_t**  vbiData, 
1068        BVBI_SMPTE291M_Description* pktDesc
1069)
1070{
1071        bool isPal;
1072        uint8_t bytesRequired;
1073
1074        BSTD_UNUSED (arg0);
1075        BSTD_UNUSED (second_id);
1076
1077        /* PAL or NTSC? */
1078        switch (BVBI_P_PALorNTSC (eVideoFormat))
1079        {
1080        case BVBI_P_SupportedVideo_PAL:
1081                isPal = true;
1082                break;
1083        case BVBI_P_SupportedVideo_NTSC:
1084                isPal = false;
1085                break;
1086        default:
1087                return BERR_TRACE (BVBI_ERR_VFMT_CONFLICT);
1088                break;
1089        }
1090
1091        /* The raw VBI data is (almost) immediate */
1092        *vbiData = packet + 2;
1093
1094        /* Some of the descriptive information cannot be checked, just echo
1095           defaults and hope for the best. */
1096        pktDesc->polarity     = polarity;
1097        pktDesc->lineNumber   = (packet[0] << 8) | packet[1];
1098
1099        /* Interpret the proprietary VBI type indicator */
1100        switch (data_id)
1101        {
1102        case 0x05:
1103                pktDesc->vbiType = BVBI_656_VbiType_USCC;
1104                bytesRequired = 4;
1105                break;
1106        case 0x01:
1107                pktDesc->vbiType = BVBI_656_VbiType_EuroCC;
1108                bytesRequired = 4;
1109                break;
1110        case 0x04:
1111                /* TODO: verify byte count */
1112                pktDesc->vbiType = BVBI_656_VbiType_NABTS;
1113                bytesRequired = 34;
1114                break;
1115        case 0x08:
1116                /* TODO: verify byte count */
1117                pktDesc->vbiType = BVBI_656_VbiType_TT;
1118                bytesRequired = 43;
1119                break;
1120        case 0x03:
1121                pktDesc->vbiType = BVBI_656_VbiType_WSS;
1122                /* TODO: verify this: */
1123                bytesRequired = 3;
1124                break;
1125        /* TODO: fix this numeric code */
1126        case 0x33:
1127                pktDesc->vbiType = 
1128                        isPal ? BVBI_656_VbiType_VPS : BVBI_656_VbiType_None;
1129                /* TODO: verify this: */
1130                bytesRequired = 2;
1131                break;
1132        default:
1133                pktDesc->vbiType = BVBI_656_VbiType_None;
1134                bytesRequired = 0;
1135                break;
1136        }
1137        if (pktDesc->vbiType == BVBI_656_VbiType_None)
1138                return BERR_TRACE (BVBI_ERR_656_PARSE);
1139
1140        /* Verify that there is enough data to copy */
1141        if (data_count < bytesRequired)
1142                return BERR_TRACE (BVBI_ERR_656_PARSE);
1143
1144        return BERR_SUCCESS;
1145}
1146
1147
1148/***************************************************************************
1149 *
1150 */
1151static uint32_t BVBI_P_P656_MoveCC  (
1152        uint8_t* vbiData, BVBI_SMPTE291M_Description* pktInfo, 
1153        bool isPal, uint16_t* usCCData)
1154{
1155        uint32_t retval = 0x0;
1156
1157        /* Consistency checks */
1158        if (pktInfo->lineNumber != 0)
1159        {
1160                int correctLine = isPal ?
1161                        ((pktInfo->polarity == BAVC_Polarity_eTopField) ? 22 : 335) :
1162                        ((pktInfo->polarity == BAVC_Polarity_eTopField) ? 21 : 284) ;
1163                if (pktInfo->lineNumber != correctLine)
1164                {
1165                        retval = BVBI_LINE_ERROR_CC_NODATA;
1166                        goto ErrorTransfer_BVBI_P_P656_MoveCC;
1167                }
1168        }
1169
1170        /* Copy the data itself */
1171        BKNI_Memcpy (usCCData, vbiData, 2);
1172
1173ErrorTransfer_BVBI_P_P656_MoveCC:
1174        return retval;
1175}
1176
1177
1178/***************************************************************************
1179 *
1180 */
1181static uint32_t BVBI_P_P656_MoveWSS  (
1182        uint8_t* vbiData, BVBI_SMPTE291M_Description* pktInfo, 
1183        bool isPal, uint16_t* usWSSData)
1184{
1185        /* Consistency checks */
1186        if (!isPal)
1187                return BVBI_LINE_ERROR_WSS_NODATA;
1188        if (pktInfo->lineNumber != 22)
1189                return BVBI_LINE_ERROR_WSS_NODATA;
1190
1191        /* Copy the data itself */
1192        BKNI_Memcpy (usWSSData, vbiData+1, 2);
1193        /* TODO: verify that the first byte is sync bits */
1194
1195        /* Success! */
1196        return 0;
1197}
1198
1199
1200/***************************************************************************
1201 *
1202 */
1203static uint32_t BVBI_P_P656_MoveTT  (
1204        uint8_t* vbiData, BVBI_SMPTE291M_Description* pktInfo, 
1205        bool isPal, BVBI_P_TTData* TTData)
1206{
1207        int startLine;
1208        int numLines;
1209        int lineOffset;
1210        int ttSize;
1211        uint8_t* start;
1212
1213        /* Calculate region of valid teletext */
1214        startLine = isPal ?
1215                ((pktInfo->polarity == BAVC_Polarity_eTopField) ?  6 : 318) :
1216                ((pktInfo->polarity == BAVC_Polarity_eTopField) ? 10 : 273) ;
1217        numLines = isPal ? 18 : 11;
1218        ttSize = isPal ? 43 : 34;
1219
1220        /* Consistency checks */
1221        if (pktInfo->lineNumber == 0)
1222        {
1223                lineOffset = 0;
1224        }
1225        else
1226        {
1227                lineOffset = pktInfo->lineNumber - startLine;
1228                if ((lineOffset < 0) || (lineOffset >= numLines))
1229                        return BVBI_LINE_ERROR_TELETEXT_NODATA;
1230        }
1231
1232        *(uint32_t*)(TTData->pucData) |= (uint32_t)(1 << lineOffset);
1233        if (TTData->ucLines < (lineOffset + 1))
1234                TTData->ucLines = lineOffset + 1;
1235
1236        /* Copy the data itself, but check for buffer overflow */
1237        start = TTData->pucData + (1 + (lineOffset * ttSize));
1238        if ((start + ttSize) > (TTData->pucData + ttSize))
1239        {
1240                return BVBI_LINE_ERROR_FLDH_CONFLICT;
1241        }
1242        BKNI_Memcpy (start, vbiData, ttSize);
1243
1244        /* Success! */
1245        return 0;
1246}
1247
1248
1249/***************************************************************************
1250 *
1251 */
1252static BERR_Code P_CheckE (uint8_t dataByte)
1253{
1254        bool computedParity = (P_bitParity[dataByte & 0x7F] != 0);
1255        bool observedParity = ((dataByte & 0x80) != 0);
1256        BERR_Code retval;
1257
1258        if (computedParity == observedParity)
1259                retval =  BERR_SUCCESS ;
1260        else
1261                retval = BERR_INVALID_PARAMETER;
1262
1263        return retval;
1264}
1265
1266
1267/***************************************************************************
1268 *
1269 */
1270static BERR_Code P_CheckEE (uint8_t dataByte)
1271{
1272        bool computedParity = (P_bitParity[dataByte & 0x3F] != 0);
1273        BERR_Code retval;
1274
1275        if (computedParity)
1276        {
1277                retval = ((dataByte & 0xC0) == 0x40) ? 
1278                        BERR_SUCCESS : BERR_INVALID_PARAMETER;
1279        }
1280        else
1281        {
1282                retval = ((dataByte & 0xC0) == 0x80) ? 
1283                        BERR_SUCCESS : BERR_INVALID_PARAMETER;
1284        }
1285
1286        return retval;
1287}
1288
1289
1290/***************************************************************************
1291 *
1292 */
1293static BERR_Code P_CheckO (uint8_t dataByte)
1294{
1295        bool computedParity = (P_bitParity[dataByte & 0x7F] != 0);
1296        bool observedParity = ((dataByte & 0x80) != 0);
1297        BERR_Code retval;
1298
1299        if (computedParity != observedParity)
1300                retval =  BERR_SUCCESS ;
1301        else
1302                retval = BERR_INVALID_PARAMETER;
1303
1304        return retval;
1305}
1306
1307
1308/***************************************************************************
1309 *
1310 */
1311static BERR_Code P_CheckEE11 (uint8_t dataByte, uint8_t* payload)
1312{
1313        bool computedParity = (P_bitParity[dataByte & 0x3F] != 0);
1314        BERR_Code retval;
1315
1316        if (computedParity)
1317        {
1318                retval = ((dataByte & 0xC0) == 0x40) ? 
1319                        BERR_SUCCESS : BERR_INVALID_PARAMETER;
1320        }
1321        else
1322        {
1323                retval = ((dataByte & 0xC0) == 0x80) ? 
1324                        BERR_SUCCESS : BERR_INVALID_PARAMETER;
1325        }
1326
1327        /* Check incorrect parity */
1328        if (retval != BERR_SUCCESS)
1329                return retval;
1330
1331        /* Check incorrect low order bits */
1332        if ((dataByte & 0x03) != 0x03)
1333                return BERR_INVALID_PARAMETER;
1334       
1335        /* Return the "payload" nibble */
1336        *payload = ((dataByte >> 2) & 0x0F);
1337
1338        /* Success! */
1339        return BERR_SUCCESS;
1340}
1341
1342
1343/***************************************************************************
1344 *
1345 */
1346static BVBI_P_SupportedVideo BVBI_P_PALorNTSC (BFMT_VideoFmt eVideoFormat)
1347{
1348        BVBI_P_SupportedVideo retval;
1349
1350        switch (eVideoFormat)
1351        {
1352    case BFMT_VideoFmt_eNTSC:
1353    case BFMT_VideoFmt_eNTSC_J:
1354                retval = BVBI_P_SupportedVideo_NTSC;
1355                break;
1356
1357    case BFMT_VideoFmt_ePAL_B:
1358    case BFMT_VideoFmt_ePAL_B1:
1359    case BFMT_VideoFmt_ePAL_D:
1360    case BFMT_VideoFmt_ePAL_D1:
1361    case BFMT_VideoFmt_ePAL_G:
1362    case BFMT_VideoFmt_ePAL_H:
1363    case BFMT_VideoFmt_ePAL_K:
1364    case BFMT_VideoFmt_ePAL_I:
1365    case BFMT_VideoFmt_ePAL_M:
1366    case BFMT_VideoFmt_ePAL_N:
1367    case BFMT_VideoFmt_ePAL_NC:
1368    case BFMT_VideoFmt_eSECAM_L:
1369    case BFMT_VideoFmt_eSECAM_B:
1370    case BFMT_VideoFmt_eSECAM_G:
1371    case BFMT_VideoFmt_eSECAM_D:
1372    case BFMT_VideoFmt_eSECAM_K:
1373    case BFMT_VideoFmt_eSECAM_H:
1374                retval = BVBI_P_SupportedVideo_PAL;
1375                break;
1376
1377        default:
1378                retval = BVBI_P_SupportedVideo_Not;
1379                break;
1380        }
1381
1382        return retval;
1383}
1384
1385
1386/***************************************************************************
1387 *
1388 */
1389static uint8_t* P_CheckControl (uint8_t* start, uint8_t* end)
1390{
1391        while ((start+2) < end)
1392        {
1393                /* Search for SAV/EAV control code */
1394                if ((start[0] == 0xFF) && (start[1] == 0x00) &&
1395                    (start[2] == 0x00))
1396                {
1397                        /* SAV/EAV control code found.  Point to it's last byte
1398                           and exit loop immediately. */
1399                        start += 3;
1400                        break;
1401                }
1402                /* Search for 16-bytes of zeroes to mark end of data */
1403                else
1404                {
1405                        int index;
1406                        bool bZeroes = true;
1407                        for (index = 0 ; index < 16 ; ++index)
1408                        {
1409                                if (start == end)
1410                                        break;
1411                                if (start[index] != 0x00)
1412                                {
1413                                        bZeroes = false;
1414                                        break;
1415                                }
1416                        }
1417                        if (bZeroes)
1418                        {
1419                                /* End of data indicated.  Point to physical end of data
1420                                   and cause outer loop to terminate. */
1421                                start = end;
1422                        }
1423                        else
1424                        {
1425                                ++start;
1426                        }
1427                }
1428        }
1429        return start;
1430}
1431
1432
1433/***************************************************************************
1434 *
1435 */
1436static uint8_t* P_CheckControl_291 (uint8_t* start, uint8_t* end)
1437{
1438        while ((start+2) < end)
1439        {
1440                /* Search for SMPTE-291M ancillary data flag */
1441                if ((start[0] == 0x00) && (start[1] == 0xFF) &&
1442                    (start[2] == 0xFF))
1443                {
1444                        /* Ancillary data flag found.  Point to it's last byte
1445                           and exit loop immediately. */
1446                        start += 3;
1447                        break;
1448                }
1449        }
1450        return start;
1451}
1452
1453/* End of file */
Note: See TracBrowser for help on using the repository browser.