source: svn/trunk/newcon3bcm2_21bu/magnum/commonutils/udp/budp_dccparse.c

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

first commit

  • Property svn:executable set to *
File size: 45.8 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2003-2011, 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: budp_dccparse.c $
11 * $brcm_Revision: Hydra_Software_Devel/5 $
12 * $brcm_Date: 12/15/11 12:07a $
13 *
14 * Module Description:
15 *
16 * Revision History:
17 *
18 * $brcm_Log: /magnum/commonutils/udp/budp_dccparse.c $
19 *
20 * Hydra_Software_Devel/5   12/15/11 12:07a nilesh
21 * SW7425-1967: Memset CC struct to 0 to prevent random data in unused
22 * fields
23 *
24 * Hydra_Software_Devel/4   12/14/11 10:59p nilesh
25 * SW7425-1967: Added support for SCTE20,SCTE21,and AFD53 in SEI userdata
26 *
27 * Hydra_Software_Devel/3   10/28/10 3:58p darnstein
28 * SW3548-2364: trivial implementation of _isr functions for parsing.
29 *
30 * Hydra_Software_Devel/2   10/21/10 4:37p darnstein
31 * SW7401-2571: cut over to the DSS userdata parser that DSS customer
32 * engineers perfer.
33 *
34 * Hydra_Software_Devel/1   7/27/10 5:06p darnstein
35 * SW3548-3022: userdata parsing software.
36 *
37 ***************************************************************************/
38
39/* For debugging */
40/* #define BUDP_P_GETUD_DUMP 1 */
41#ifdef BUDP_P_GETUD_DUMP
42static const char* BUDP_P_Getud_Filename = "userdata.getud";
43#include <stdio.h>
44#endif
45
46#include "bstd.h"
47#include "bavc.h"
48#include "bdbg.h"
49#include "bkni.h"
50#include "budp.h"
51#include "budp_bitread.h"
52#include "budp_dccparse.h"
53
54BDBG_MODULE(BUDP);
55
56
57/***************************************************************************
58* Private data types
59***************************************************************************/
60
61/* Just used to switch among three types of internal parsers */
62typedef enum {
63        ParserType_eMpeg,     /* Good old MPEG-2 userdata.       */
64        ParserType_eSEI       /* DSS userdata, AVC flavor (SEI). */
65} ParserType;
66
67typedef struct {
68        BUDP_DCCparse_Format type;
69        BERR_Code (*parser) (
70                 const BAVC_USERDATA_info*     pUserdata_info,
71                BUDP_Bitread_Context* pReader, 
72                size_t                                   length,
73                size_t*                  pBytesParsed,
74                uint8_t*                 pcc_count,
75                BUDP_DCCparse_ccdata* pCCdata
76        );
77} DigitalParser;
78
79
80/***************************************************************************
81* Forward declarations of static (private) functions
82***************************************************************************/
83
84static BERR_Code BUDP_P_DCCparse ( 
85        ParserType               eParserType,
86        const BAVC_USERDATA_info*      pUserdata_info,
87        size_t                   offset,
88        size_t*                  pBytesParsed,
89        uint8_t*                 pcc_count,
90        BUDP_DCCparse_ccdata* pCCdata);
91static size_t FindMpegUserdataStart (
92        BUDP_Bitread_Context* pREader, size_t length);
93static size_t FindSeiUserdataStart (
94        BUDP_Bitread_Context* pREader, size_t length);
95static BERR_Code ParseDVS157Data (
96        const BAVC_USERDATA_info*      pUserdata_info,
97        BUDP_Bitread_Context* pReader, 
98        size_t                                   length,
99        size_t*                  pBytesParsed,
100        uint8_t*                 pcc_count,
101        BUDP_DCCparse_ccdata* pCCdata);
102static BERR_Code ParseATSC53Data (
103        const BAVC_USERDATA_info*      pUserdata_info,
104        BUDP_Bitread_Context* pReader, 
105        size_t                                   length,
106        size_t*                  pBytesParsed,
107        uint8_t*                 pcc_count,
108        BUDP_DCCparse_ccdata* pCCdata);
109static BERR_Code ParseAFD53Data (
110        const BAVC_USERDATA_info*      pUserdata_info,
111        BUDP_Bitread_Context* pReader, 
112        size_t                                   length,
113        size_t*                  pBytesParsed,
114        uint8_t*                 pcc_count,
115        BUDP_DCCparse_ccdata* pCCdata);
116static BERR_Code ParseDVS053Data (
117        const BAVC_USERDATA_info*      pUserdata_info,
118        BUDP_Bitread_Context* pReader, 
119        size_t                                   length,
120        size_t*                  pBytesParsed,
121        uint8_t*                 pcc_count,
122        BUDP_DCCparse_ccdata* pCCdata);
123static BERR_Code ParseSEIData (
124        const BAVC_USERDATA_info*      pUserdata_info,
125        BUDP_Bitread_Context* pReader,
126        size_t                                   length,
127        size_t*                  pBytesParsed,
128        uint8_t*                 pcc_count,
129        BUDP_DCCparse_ccdata* pCCdata
130);
131static BERR_Code ParseSEIData2 (
132        const BAVC_USERDATA_info*      pUserdata_info,
133        BUDP_Bitread_Context* pReader,
134        size_t                                   length,
135        size_t*                  pBytesParsed,
136        uint8_t*                 pcc_count,
137        BUDP_DCCparse_ccdata* pCCdata
138);
139
140static int swap_bits (int src);
141
142#ifdef BUDP_P_GETUD_DUMP
143static void dump_getud (
144        const BAVC_USERDATA_info* pUserdata_info, size_t offset);
145#endif
146
147/*
148 * This is the collection of methods for setting field polarity (top vs.
149 * bottom) for closed caption data.
150 */
151/* Uses only cc_type attribute */
152static void SetFieldsParity_SIMPLE (
153        BUDP_DCCparse_ccdata* pCCdata,
154        uint8_t                  cc_count,
155        const BAVC_USERDATA_info*      pUserdata_info);
156/* Uses cc_type attribute and "top field first" attribute. */
157static void SetFieldsParity_TFF (
158        BUDP_DCCparse_ccdata* pCCdata,
159        uint8_t                  cc_count,
160        const BAVC_USERDATA_info*      pUserdata_info);
161/* Uses only order of data presented. */
162static void SetFieldsParity_NOCCTYPE (
163        BUDP_DCCparse_ccdata* pCCdata,
164        uint8_t                  cc_count,
165        const BAVC_USERDATA_info*      pUserdata_info);
166/* Uses field_number attribute */
167static void SetFieldsParity_FIELDNUMBER (
168        BUDP_DCCparse_ccdata* pCCdata,
169        uint8_t                  cc_count,
170        const BAVC_USERDATA_info*      pUserdata_info);
171/* Special method just for CC data from SEI */
172static void SetFieldsParity_SEI (
173        BUDP_DCCparse_ccdata* pCCdata,
174        uint8_t                  cc_count,
175        const BAVC_USERDATA_info*      pUserdata_info);
176
177/*
178 * These macros determine which field polarity method (see above paragraph)
179 * to use for parsing ATSC, DVS, and SEI closed caption data. You can override
180 * these choices from the compiler command line. Make a choice from the above
181 * paragraph.
182 */
183#ifndef BUDP_SETFIELDSPARITY_ATSC
184#define BUDP_SETFIELDSPARITY_ATSC SetFieldsParity_SIMPLE
185#endif
186#ifndef BUDP_SETFIELDSPARITY_DVS
187#define BUDP_SETFIELDSPARITY_DVS SetFieldsParity_FIELDNUMBER
188#endif
189#ifndef BUDP_SETFIELDSPARITY_SEI
190#define BUDP_SETFIELDSPARITY_SEI SetFieldsParity_SEI
191#endif
192
193
194/***************************************************************************
195* Static data (tables, etc.)
196***************************************************************************/
197
198/* The array of digital CC data parsers.  It does not include the DSS parser.
199 * The DSS parser must be handled as a special case.  This is because this
200 * software collection cannot discover on its own that it is dealing with DSS
201 * data.  This software _can_ discriminate between the other forms of CC data,
202 * listed in the following array:
203 */
204static const DigitalParser s_mpegParsers[] = {
205#ifndef ACB612
206        {BUDP_DCCparse_Format_DVS157, ParseDVS157Data},
207#endif
208        {BUDP_DCCparse_Format_ATSC53, ParseATSC53Data},
209#ifndef ACB612
210        {BUDP_DCCparse_Format_DVS053, ParseDVS053Data},
211#endif
212        {BUDP_DCCparse_Format_AFD53, ParseAFD53Data}
213};
214#define NUM_MPEG_PARSERS (sizeof(s_mpegParsers) / sizeof(s_mpegParsers[0]))
215
216static const DigitalParser s_seiParsers[] = {
217        {BUDP_DCCparse_Format_SEI, ParseSEIData},
218        {BUDP_DCCparse_Format_SEI2, ParseSEIData2},
219};
220#define NUM_SEI_PARSERS (sizeof(s_seiParsers) / sizeof(s_seiParsers[0]))
221
222static const bool bByteswap = (BSTD_CPU_ENDIAN == BSTD_ENDIAN_LITTLE);
223
224
225/***************************************************************************
226* Implementation of "BUDP_DCCparse_" API functions
227***************************************************************************/
228
229
230/***************************************************************************
231 *
232 */
233BERR_Code BUDP_DCCparse_isr ( 
234        const BAVC_USERDATA_info*      pUserdata_info, 
235        size_t                   offset, 
236        size_t*                  pBytesParsed,
237        uint8_t*                 pcc_count,
238        BUDP_DCCparse_ccdata* pCCdata
239)
240{
241        return 
242                BUDP_P_DCCparse (
243                        ParserType_eMpeg, pUserdata_info, offset, 
244                        pBytesParsed, pcc_count, pCCdata);
245}
246
247/***************************************************************************
248 *
249 */
250BERR_Code BUDP_DCCparse_SEI_isr ( 
251        const BAVC_USERDATA_info*      pUserdata_info, 
252        size_t                   offset, 
253        size_t*                  pBytesParsed,
254        uint8_t*                 pcc_count,
255        BUDP_DCCparse_ccdata* pCCdata
256)
257{
258        return 
259                BUDP_P_DCCparse (
260                        ParserType_eSEI, pUserdata_info, offset, 
261                        pBytesParsed, pcc_count, pCCdata);
262}
263
264
265/***************************************************************************
266* Implementation of private (static) functions
267***************************************************************************/
268
269/***************************************************************************
270 *
271 */
272static BERR_Code BUDP_P_DCCparse ( 
273        ParserType               eParserType,
274        const BAVC_USERDATA_info*      pUserdata_info, 
275        size_t                   offset, 
276        size_t*                  pBytesParsed,
277        uint8_t*                 pcc_count,
278        BUDP_DCCparse_ccdata* pCCdata
279)
280{
281        size_t bytesParsedSub;
282        size_t length;
283        uint8_t* userdata;
284        unsigned int iparser;
285        BERR_Code eErr;
286        BUDP_Bitread_Context reader; 
287        BUDP_Bitread_Context savedReader; 
288
289        BDBG_ENTER(BUDP_DCCparse);
290
291        /* Check for obvious errors from user */
292        if ((pUserdata_info == 0x0) ||
293            (pBytesParsed   == 0x0) ||
294            (pcc_count      == 0x0) ||
295            (pCCdata        == 0x0)   )
296        {
297                return BERR_INVALID_PARAMETER;
298        }
299
300        /* Programming note:  all function parameters are now validated */
301
302
303#ifdef BUDP_P_GETUD_DUMP
304        dump_getud (pUserdata_info, offset);
305#endif
306
307        /* Take care of a special case */
308        userdata = (uint8_t*)(pUserdata_info->pUserDataBuffer) + offset;
309        length   = pUserdata_info->ui32UserDataBufSize - offset;
310        if (length < 4)
311        {
312                *pBytesParsed = length;
313                return BERR_BUDP_NO_DATA;
314        }
315
316        /* Prepare to play with bits */
317        BUDP_Bitread_Init (&reader, bByteswap, userdata);
318
319        switch (eParserType)
320        {
321        case ParserType_eMpeg:
322
323                /* jump past the first MPEG userdata start code */
324                bytesParsedSub = FindMpegUserdataStart (&reader, length);
325                *pBytesParsed = bytesParsedSub;
326                length -= bytesParsedSub;
327                savedReader = reader;
328
329                /* If we did not find a start code, bail out now */
330                if (length == 0)
331                {
332                        return BERR_BUDP_NO_DATA;
333                }
334
335                /*********************************************************************\
336                * Programming note:  each of the parsers will give up and return
337                * BERR_BUDP_NO_DATA if it finds the wrong identifier byte. 
338                \*********************************************************************/
339
340                /* Try all the available parsers */
341                for (iparser = 0 ; iparser < NUM_MPEG_PARSERS ; ++iparser)
342                {
343                        reader = savedReader;
344                        eErr = (*s_mpegParsers[iparser].parser) (
345                                pUserdata_info, &reader, length, 
346                                &bytesParsedSub, pcc_count, pCCdata);
347                        switch (eErr)
348                        {
349                        case BERR_SUCCESS:
350                                /* Sarnoff compliance check */
351                                if ((pUserdata_info->eUserDataType == BAVC_USERDATA_Type_eSeq) 
352                                        ||
353                                    (pUserdata_info->eUserDataType == BAVC_USERDATA_Type_eGOP))
354                                {
355                                        eErr = BERR_BUDP_SOURCE_CHECK;
356                                }
357                                /* fall into the next case */
358                        case BERR_BUDP_PARSE_ERROR:
359                                *pBytesParsed += bytesParsedSub;
360                                BDBG_LEAVE(BUDP_DCCparse);
361                                return eErr;
362                                break;
363                        case BERR_BUDP_NO_DATA:
364                                break;
365                        default:
366                                /* Programming error */
367                                BDBG_ASSERT (false);
368                                break;
369                        }
370                }
371                break;
372
373        case ParserType_eSEI:
374
375                /* jump past the first SEI userdata start code */
376                bytesParsedSub = FindSeiUserdataStart (&reader, length);
377                *pBytesParsed = bytesParsedSub;
378                length -= bytesParsedSub;
379                savedReader = reader;
380
381                /* If we did not find a start code, bail out now */
382                if (length == 0)
383                {
384                        return BERR_BUDP_NO_DATA;
385                }
386               
387                /*********************************************************************\
388                * Programming note:  each of the parsers will give up and return
389                * BERR_BUDP_NO_DATA if it finds the wrong identifier byte. 
390                \*********************************************************************/
391
392                /* Try all available parsers */
393                for (iparser = 0 ; iparser < NUM_SEI_PARSERS ; ++iparser)
394                {
395                        reader = savedReader;
396                        eErr = (*s_seiParsers[iparser].parser) (
397                                pUserdata_info, &reader, length, 
398                                &bytesParsedSub, pcc_count, pCCdata);
399                        switch (eErr)
400                        {
401                                case BERR_SUCCESS:
402                                case BERR_BUDP_PARSE_ERROR:
403                                        *pBytesParsed += bytesParsedSub;
404                                        BDBG_LEAVE(BUDP_DCCparse);
405                                        return eErr;
406                                        break;
407                                case BERR_BUDP_NO_DATA:
408                                        break;
409                                default:
410                                        /* Programming error */
411                                        BDBG_ASSERT (false);
412                                        break;
413                        }
414                }
415        break;
416
417        default:
418                BDBG_ERR (("Programming error"));
419                BDBG_ASSERT (0);
420                break;
421
422        }
423
424        /* Programming note:
425         * None of the parsers liked this bit of userdata.
426         * It would be more elegant to skip to the next start code
427         * before returning.  But it is more efficient to simply
428         * stop parsing. */
429
430        /* No userdata was found */
431        BDBG_LEAVE(BUDP_DCCparse);
432        return BERR_BUDP_NO_DATA;
433}
434
435/***************************************************************************
436 * This function finds the next userdata startcode 0x000001B2.  It
437 * indicates the byte following this startcode by its return value.
438 * If no startcode was found, it simply returns the length of the
439 * input data.
440 */
441static size_t FindMpegUserdataStart (
442        BUDP_Bitread_Context* pReader, size_t length)
443{
444    size_t count = 0;
445        uint8_t saved[4];
446
447        /* Special case (failure) */
448        if (length < 4)
449                return length;
450
451        /* Initialize */
452        saved[1] = BUDP_Bitread_Byte (pReader);
453        saved[2] = BUDP_Bitread_Byte (pReader);
454        saved[3] = BUDP_Bitread_Byte (pReader);
455
456        while (length >= 4)
457        { 
458                /* Read in another byte */
459                saved[0] = saved[1];
460                saved[1] = saved[2];
461                saved[2] = saved[3];
462                saved[3] = BUDP_Bitread_Byte (pReader);
463
464                if ((saved[0] == 0x00) &&
465                    (saved[1] == 0x00) &&
466                        (saved[2] == 0x01) &&
467                        (saved[3] == 0xB2)    ) 
468                {
469                        /* Found it! */
470                        break;
471                }
472
473                /* proceed to the next byte */
474                --length;
475                ++count;
476        }
477
478        if (length >= 4)
479        {
480                /* found the pattern before the end of stream */   
481                return count + 4;
482        }
483        else
484        {
485                /* Didn't find any start code */
486                return count + 3;
487        }
488}
489
490/***************************************************************************
491 * This function finds the next userdata startcode 0x00000106.  It
492 * indicates the byte following this startcode by its return value.
493 * If no startcode was found, it simply returns the length of the
494 * input data.
495 */
496static size_t FindSeiUserdataStart (
497        BUDP_Bitread_Context* pReader, size_t length)
498{
499    size_t count = 0;
500        uint8_t saved[4];
501
502        /* Special case (failure) */
503        if (length < 4)
504                return length;
505
506        /* Initialize */
507        saved[1] = BUDP_Bitread_Byte (pReader);
508        saved[2] = BUDP_Bitread_Byte (pReader);
509        saved[3] = BUDP_Bitread_Byte (pReader);
510
511        while (length >= 4)
512        { 
513                /* Read in another byte */
514                saved[0] = saved[1];
515                saved[1] = saved[2];
516                saved[2] = saved[3];
517                saved[3] = BUDP_Bitread_Byte (pReader);
518
519                if ((saved[0] == 0x00) &&
520                    (saved[1] == 0x00) &&
521                        (saved[2] == 0x01) &&
522                        (saved[3] == 0x06)    ) 
523                {
524                        /* Found it! */
525                        break;
526                }
527
528                /* proceed to the next byte */
529                --length;
530                ++count;
531        }
532
533        if (length >= 4)
534        {
535                /* found the pattern before the end of stream */   
536                return count + 4;
537        }
538        else
539        {
540                /* Didn't find any start code */
541                return count + 3;
542        }
543}
544
545/* TODO: figure out where to put this */
546#define MPEG_DVS157_VBI_DATA_FLAG 0x03
547
548/***************************************************************************
549 * This function parses DVS 157 data.  It assumes that the userdata
550 * startcode 0x000001B2 has just been read.
551 */
552static BERR_Code ParseDVS157Data (
553        const BAVC_USERDATA_info*      pUserdata_info,
554        BUDP_Bitread_Context* pReader,
555        size_t                                   length,
556        size_t*                  pBytesParsed,
557        uint8_t*                 pcc_count,
558        BUDP_DCCparse_ccdata* pCCdata
559)
560{
561        size_t bitsParsed;
562        int icount;
563
564        /* Special case */
565        if (length == 0)
566        {   
567                *pcc_count = 0;
568                return BERR_BUDP_PARSE_ERROR;
569        }
570
571        /* user_data_type_code(8) */
572        if (BUDP_Bitread_Byte (pReader) != MPEG_DVS157_VBI_DATA_FLAG) 
573        {
574                /* not DVS 157 data */
575                *pBytesParsed = 1;
576                *pcc_count = 0;
577                return BERR_BUDP_NO_DATA;
578        }
579
580        /* Start things off by recognizing that we have parsed one byte.
581           If an error occurs now, don't bother updating the count of
582           parsed bytes.
583        */
584        --length;
585        *pBytesParsed = 1;
586
587        if (length == 0)
588        {   
589                /* Packet is too short */
590                *pcc_count = 0;
591                return BERR_BUDP_PARSE_ERROR;
592        }
593
594        /* Skip '1000 000' bits (7) */
595        /* vbi_data_flag(1) */
596        if (!(BUDP_Bitread_Byte (pReader) & 0x01))
597        {
598                /* No data for us.  Prevent other parsers from trying though. */
599                *pcc_count = 0;
600                return BERR_SUCCESS;
601        }
602
603        --length;
604        *pBytesParsed += 1;
605        if (length == 0)
606        {   
607                /* Packet is too short */
608                *pcc_count = 0;
609                return BERR_BUDP_PARSE_ERROR;
610        }
611
612        /* Start the bit level parsing */
613        *pcc_count = BUDP_Bitread_Read (pReader, 5);
614        bitsParsed = 5;
615
616        for (icount = 0 ; icount < *pcc_count ; ++icount)
617        {
618           BKNI_Memset( &pCCdata[icount], 0, sizeof(pCCdata[icount]));
619
620                /* Each sub-packet of data is 26 bits */
621                if (length < 4)
622                {
623                        /* Minimum packet length */
624                        return BERR_BUDP_PARSE_ERROR;
625                }
626
627                /* Not part of DVS157 standard! */
628                pCCdata[icount].cc_valid = 1;
629
630                pCCdata[icount].cc_priority = BUDP_Bitread_Read (pReader, 2);
631
632                pCCdata[icount].seq.field_number = BUDP_Bitread_Read (pReader, 2);
633
634                pCCdata[icount].line_offset = BUDP_Bitread_Read (pReader, 5);
635
636                pCCdata[icount].cc_data_1 = 
637                        swap_bits(BUDP_Bitread_Byte (pReader));
638                pCCdata[icount].cc_data_2 = 
639                        swap_bits(BUDP_Bitread_Byte (pReader));
640                /* marker bit(1) */ 
641                (void)BUDP_Bitread_Read (pReader, 1);
642
643                /* Check for length violation again */
644                /* bitsParsed += 26; */
645                if (bitsParsed < 6)
646                {
647                        length -= 3;
648                        *pBytesParsed += 3;
649                        bitsParsed += 2;
650                }
651                else
652                {
653                        length -= 4;
654                        *pBytesParsed += 4;
655                        bitsParsed -= 6;
656                }
657                pCCdata[icount].format = BUDP_DCCparse_Format_DVS157;
658        }
659
660        BUDP_SETFIELDSPARITY_DVS (pCCdata, *pcc_count, pUserdata_info);
661        return BERR_SUCCESS;
662}
663
664/***************************************************************************
665 * This function parses DVS 053 data.  It assumes that the userdata
666 * startcode 0x000001B2 has just been read.
667 */
668static BERR_Code ParseDVS053Data (
669        const BAVC_USERDATA_info*      pUserdata_info,
670        BUDP_Bitread_Context* pReader,
671        size_t                                   length,
672        size_t*                  pBytesParsed,
673        uint8_t*                 pcc_count,
674        BUDP_DCCparse_ccdata* pCCdata
675)
676{
677        unsigned int cc_count;
678        unsigned int icount;
679        int data_found;
680
681        /* Start counting */
682        *pcc_count = 0;
683
684        /* Special case */
685        if (length < 4)
686        {   
687                return BERR_BUDP_PARSE_ERROR;
688        }
689
690        /* ATSC identifier (4) */
691        if ((BUDP_Bitread_Byte (pReader) != 0x47) ||
692            (BUDP_Bitread_Byte (pReader) != 0x41) ||
693            (BUDP_Bitread_Byte (pReader) != 0x39) ||
694            (BUDP_Bitread_Byte (pReader) != 0x34)   )
695        {
696                /* not DVS 053 data */
697                *pBytesParsed = 4;
698                return BERR_BUDP_NO_DATA;
699        }
700
701        /* Start things off by recognizing that we have parsed four bytes.
702           If an error occurs now, don't bother updating the count of
703           parsed bytes.
704        */
705        length -= 4;
706        *pBytesParsed = 4;
707
708        if (length == 0)
709        {   
710                /* Empty! */
711                return BERR_BUDP_PARSE_ERROR;
712        }
713
714        /* user_data_type_code(8) */
715        if (BUDP_Bitread_Byte (pReader) != 0x04)
716        {
717                /* not DVS 053 data */
718                *pBytesParsed = 5;
719                return BERR_BUDP_NO_DATA;
720        }
721
722        --length;
723        *pBytesParsed += 1;
724        if (length == 0)
725        {   
726                /* Packet too short */
727                return BERR_BUDP_PARSE_ERROR;
728        }
729
730        /* Skip marker bits(3) and dig out the count of cc data pairs(5) */
731        cc_count = BUDP_Bitread_Byte (pReader) & 0x1F;
732
733        /* This will be the last length check */
734        --length;
735        *pBytesParsed += 1;
736        if (length < (3 * cc_count))
737        {   
738                /* Packet too short */
739                return BERR_BUDP_PARSE_ERROR;
740        }
741        *pBytesParsed += (3 * cc_count);
742
743        /* Dig out the closed caption data pairs */
744        data_found = 0;
745        for (icount = 0 ; icount < cc_count ; ++icount)
746        {
747                /* additional_cc_valid(1) */
748                uint32_t additional_cc_valid = BUDP_Bitread_Read (pReader, 1);
749
750           BKNI_Memset( &pCCdata[data_found], 0, sizeof(pCCdata[data_found]));
751
752                pCCdata[data_found].cc_valid = additional_cc_valid;
753       
754                /* additional_cc_line_offset(5) */
755                pCCdata[data_found].line_offset = BUDP_Bitread_Read (pReader, 5);
756
757                /* additional_cc_field_number(2) */
758                pCCdata[data_found].seq.field_number = 
759                        BUDP_Bitread_Read (pReader, 2);
760
761                /* additional_cc_data_1(8) */
762                pCCdata[data_found].cc_data_1 = 
763                        BUDP_Bitread_Byte (pReader);
764
765                /* additional_cc_data_2(8) */
766                pCCdata[data_found].cc_data_2 = 
767                        BUDP_Bitread_Byte (pReader);
768
769                pCCdata[data_found].format = BUDP_DCCparse_Format_DVS053;
770
771                /* Update count of items written to output data */
772                ++data_found;
773        }
774
775        BUDP_SETFIELDSPARITY_DVS (pCCdata, *pcc_count, pUserdata_info);
776
777        *pcc_count = data_found;
778        return BERR_SUCCESS;
779}
780
781
782static BERR_Code ParseAFD53Data (
783        const BAVC_USERDATA_info*      pUserdata_info,
784        BUDP_Bitread_Context*       pReader,
785        size_t                         length,
786        size_t*                        pBytesParsed,
787        uint8_t*                       pcc_count,
788        BUDP_DCCparse_ccdata*       pCCdata
789)
790{
791        uint32_t active_format_flag, active_format_data;
792
793        BSTD_UNUSED (pUserdata_info);
794
795        /* Indicate no data found (yet) */
796        *pcc_count = 0;
797
798        if (length < 4)
799        {   
800                return BERR_BUDP_PARSE_ERROR;
801        }
802
803        /* AFD identifier (32) */
804        if ((BUDP_Bitread_Byte (pReader) != 0x44) ||
805            (BUDP_Bitread_Byte (pReader) != 0x54) ||
806            (BUDP_Bitread_Byte (pReader) != 0x47) ||
807            (BUDP_Bitread_Byte (pReader) != 0x31)   )
808        {
809                /* not AFD-53 data */
810                *pBytesParsed = 4;
811                return BERR_BUDP_NO_DATA;
812        }
813       
814
815        length -= 4;
816        *pBytesParsed = 4;
817
818        if (length == 0)
819        {   
820                /* Empty! */
821                return BERR_BUDP_PARSE_ERROR;
822        }
823
824        (void)BUDP_Bitread_Read (pReader, 1);
825
826        active_format_flag = BUDP_Bitread_Read (pReader, 1);
827
828        if(!BUDP_Bitread_Read (pReader, 6)){
829                *pBytesParsed = 5;
830                return BERR_BUDP_NO_DATA;
831        }
832
833        --length;
834        *pBytesParsed = 5;
835        if (length == 0)
836        {   
837                /* Packet too short */
838                return BERR_BUDP_PARSE_ERROR;
839        }
840
841        if(active_format_flag)
842        {
843                active_format_data = BUDP_Bitread_Byte (pReader);
844                pCCdata[0].active_format = (uint8_t)active_format_data & 0x0f;
845
846                --length;
847                *pBytesParsed = 6;
848        }
849       
850
851        pCCdata[0].format    = BUDP_DCCparse_Format_AFD53;
852        pCCdata[0].polarity  =       BAVC_Polarity_eTopField;
853        pCCdata[0].bIsAnalog = true;
854        pCCdata[0].cc_valid  =    1;
855        *pcc_count = 1;
856
857        return BERR_SUCCESS;
858
859}
860
861/***************************************************************************
862 * This function parses ATSC 53 data.  It assumes that the userdata
863 * startcode 0x000001B2 has just been read.
864 */
865static BERR_Code ParseATSC53Data (
866        const BAVC_USERDATA_info*      pUserdata_info,
867        BUDP_Bitread_Context* pReader,
868        size_t                                   length,
869        size_t*                  pBytesParsed,
870        uint8_t*                 pcc_count,
871        BUDP_DCCparse_ccdata* pCCdata
872)
873{
874        unsigned int cc_count;
875        unsigned int cc_valid;
876        unsigned int icount;
877        int data_found;
878
879        BSTD_UNUSED (pUserdata_info);
880
881        /* Start counting */
882        *pcc_count = 0;
883
884        /* Start travelling pointer into data */
885        if (length < 4)
886        {   
887                return BERR_BUDP_PARSE_ERROR;
888        }
889
890        /* ATSC identifier (32) */
891        if ((BUDP_Bitread_Byte (pReader) != 0x47) ||
892            (BUDP_Bitread_Byte (pReader) != 0x41) ||
893            (BUDP_Bitread_Byte (pReader) != 0x39) ||
894            (BUDP_Bitread_Byte (pReader) != 0x34)   )
895        {
896                /* not ATSC-53 data */
897                *pBytesParsed = 4;
898                return BERR_BUDP_NO_DATA;
899        }
900
901        /* Start things off by recognizing that we have parsed four bytes.
902           If an error occurs now, don't bother updating the count of
903           parsed bytes.
904        */
905        length -= 4;
906        *pBytesParsed = 4;
907
908        if (length == 0)
909        {   
910                /* Empty! */
911                return BERR_BUDP_PARSE_ERROR;
912        }
913
914        /* user_data_type_code(8) */
915        if (BUDP_Bitread_Byte (pReader) != 0x03)
916        {
917                /* not ATSC-53 data */
918                *pBytesParsed = 5;
919                return BERR_BUDP_NO_DATA;
920        }
921
922        --length;
923        *pBytesParsed = 5;
924        if (length == 0)
925        {   
926                /* Packet too short */
927                return BERR_BUDP_PARSE_ERROR;
928        }
929
930        /* Skip process_em_data_flag(1) */
931        (void)BUDP_Bitread_Read (pReader, 1);
932       
933        /* Dig out process_cc_data_flag(1) */
934        if (!BUDP_Bitread_Read (pReader, 1))
935        {
936                /* No closed caption data to process */
937                *pBytesParsed = 6;
938                return BERR_BUDP_NO_DATA;
939        }
940
941        /* Skip additional_data_flag(1) */
942        (void)BUDP_Bitread_Read (pReader, 1);
943
944        /* Dig out the count of cc data pairs */
945        cc_count = BUDP_Bitread_Read (pReader, 5);
946
947        --length;
948        *pBytesParsed = 6;
949        if (length == 0)
950        {   
951                /* Packet too short */
952                return BERR_BUDP_PARSE_ERROR;
953        }
954
955        /* Skip em_data(8) */
956        (void)BUDP_Bitread_Byte (pReader);
957
958        /* This will be the last length check */
959        --length;
960        *pBytesParsed = 7;
961        if (length < (3 * cc_count))
962        {   
963                /* Packet too short */
964                return BERR_BUDP_PARSE_ERROR;
965        }
966        *pBytesParsed += (3 * cc_count);
967
968        /* Dig out the closed caption data pairs */
969        data_found = 0;
970        for (icount = 0 ; icount < cc_count ; ++icount)
971        {
972                /* Skip marker bits(5) */
973                (void)BUDP_Bitread_Read (pReader, 5);
974
975           BKNI_Memset( &pCCdata[data_found], 0, sizeof(pCCdata[data_found]));
976
977                /* cc_valid(1) */
978                cc_valid = BUDP_Bitread_Read (pReader, 1);
979                pCCdata[data_found].cc_valid = cc_valid;
980       
981                /* cc_type(2) */
982                pCCdata[data_found].seq.cc_type = BUDP_Bitread_Read (pReader, 2);
983
984                /* Kludge */
985                pCCdata[data_found].line_offset = 11;
986
987                /* additional_cc_data_1(8) */
988                pCCdata[data_found].cc_data_1 = 
989                        BUDP_Bitread_Byte (pReader);
990
991                /* additional_cc_data_2(8) */
992                pCCdata[data_found].cc_data_2 = 
993                        BUDP_Bitread_Byte (pReader);
994
995                pCCdata[data_found].format = BUDP_DCCparse_Format_ATSC53;
996
997                /* Update count of items written to output data */
998                /* Store data ordinary, closed caption data as well as CC708 data */
999                ++data_found;
1000        }
1001
1002        BUDP_SETFIELDSPARITY_ATSC (pCCdata, data_found, pUserdata_info);
1003
1004        *pcc_count = data_found;
1005        return BERR_SUCCESS;
1006}
1007
1008/***************************************************************************
1009 * This function parses SEI user data.  It assumes that the userdata
1010 * startcode 0x000001B2 has just been read. This is the old format used by a
1011 * particular customer circa June 2005.
1012 */
1013static BERR_Code ParseSEIData (
1014        const BAVC_USERDATA_info*      pUserdata_info,
1015        BUDP_Bitread_Context* pReader,
1016        size_t                                   length,
1017        size_t*                  pBytesParsed,
1018        uint8_t*                 pcc_count,
1019        BUDP_DCCparse_ccdata* pCCdata
1020)
1021{
1022        int index;
1023        uint8_t seiType;
1024        uint8_t userDataLength;
1025        uint8_t country_code;
1026        uint16_t manufacturers_code;
1027        uint8_t user_data_type_code;
1028        uint8_t user_data_code_length;
1029        uint8_t miscBits;
1030        uint8_t process_cc_data_flag;
1031        uint8_t cc_count;
1032        uint8_t cc_valid, cc_type, cc_data_1, cc_data_2;
1033
1034        /* Start counting */
1035        *pcc_count = 0;
1036        *pBytesParsed = 0;
1037
1038        /* We must have at least one type byte and a length byte */
1039        if (length < 2)
1040        {   
1041                return BERR_BUDP_NO_DATA;
1042        }
1043
1044        /* Read 8-bit type field */
1045        seiType = BUDP_Bitread_Byte (pReader);
1046        (*pBytesParsed)++;
1047        if (seiType != 0x04)
1048        {
1049                return BERR_BUDP_NO_DATA;;
1050        }
1051
1052        /* Read 8-bit length field */
1053        userDataLength = BUDP_Bitread_Byte (pReader);
1054        (*pBytesParsed)++;
1055
1056        /* A consistency check */
1057        if (userDataLength > (unsigned)(length - 2))
1058        {
1059                return BERR_BUDP_PARSE_ERROR;
1060        }
1061
1062        /* Prevent access violations */
1063        if (userDataLength < 3)
1064        {
1065                return BERR_BUDP_PARSE_ERROR;
1066        }
1067
1068        /* Read 8-bit country code */
1069        country_code = BUDP_Bitread_Byte (pReader);
1070        (*pBytesParsed)++;
1071        --userDataLength;
1072        if (country_code != 0xb5)
1073        {
1074                return BERR_BUDP_NO_DATA;
1075        }
1076
1077        /* Read 16-bit manufacturers code */
1078        manufacturers_code  = BUDP_Bitread_Byte (pReader) << 8;
1079        manufacturers_code |= BUDP_Bitread_Byte (pReader);
1080        (*pBytesParsed) += 2;
1081        userDataLength -= 2;
1082        if (manufacturers_code != 0x002F)
1083        {
1084                return BERR_BUDP_NO_DATA;
1085        }
1086
1087        while(userDataLength >= 2)
1088        {
1089                /* Read 8-bit type field */
1090                user_data_type_code = BUDP_Bitread_Byte (pReader);
1091                (*pBytesParsed)++;
1092                --userDataLength;
1093
1094                /* Read another length field */
1095                user_data_code_length = BUDP_Bitread_Byte (pReader);
1096                (*pBytesParsed)++;
1097                --userDataLength;
1098
1099                if (user_data_type_code == 3) 
1100                { 
1101                        /* Begin cc_data */
1102
1103                        /* Read and check reserved, process_cc_data_flag, and
1104                           additional_data_flag (3 bits total) */
1105                        miscBits =  BUDP_Bitread_Read (pReader, 1);
1106                        if (miscBits != 0x01)
1107                        {
1108                                return BERR_BUDP_PARSE_ERROR;
1109                        }
1110                        process_cc_data_flag = BUDP_Bitread_Read (pReader, 1);
1111                        miscBits =  BUDP_Bitread_Read (pReader, 1);
1112                        if (miscBits != 0x00)
1113                        {
1114                                return BERR_BUDP_PARSE_ERROR;
1115                        }
1116
1117                        /* Read cc_count (5 bits) */
1118                        cc_count = BUDP_Bitread_Read (pReader, 5);
1119
1120                        (*pBytesParsed)++;
1121                        --userDataLength;
1122
1123                        /* Consistency check */
1124                        if ((user_data_code_length != (cc_count * 3 + 3)) &&
1125                            (user_data_code_length != (cc_count * 3 + 4))    )
1126                        {
1127                                return BERR_BUDP_PARSE_ERROR;
1128                        }
1129                        /* Programming note: the second clause above is to support older,
1130                         * non-compliant bitstreams.
1131                         */
1132
1133                        /* Read 8 reserved bits */
1134                        miscBits = BUDP_Bitread_Byte (pReader);
1135                        if (miscBits != 0xFF)
1136                        {
1137                                return BERR_BUDP_PARSE_ERROR;
1138                        }
1139                        (*pBytesParsed)++;
1140                        --userDataLength;
1141
1142                        /* Length check for the following inner loop, plus trailing byte. */
1143                        if (userDataLength < (cc_count * 3 + 1))
1144                        {
1145                                return BERR_BUDP_PARSE_ERROR;
1146                        }
1147
1148                        for (index = 0 ; index < cc_count ; ++index)
1149                        {
1150                                /* Read and check marker bits (5) */
1151                                miscBits = BUDP_Bitread_Read (pReader, 5);
1152                                if (miscBits != 0x1F)
1153                                {
1154                                        /* MiscBits should always be 0x1f but in practice
1155                                        some streams do not have them set and this would
1156                                        cause us to throw the whole thing out. So lets
1157                                        just continue after printing a warning.
1158                                        */
1159                                        /*return BERR_BUDP_PARSE_ERROR;*/
1160                                        BDBG_WRN(("Marker bits not set"));
1161                                }
1162
1163                                /* Read some one-bit descriptors (2) */
1164                                cc_valid = BUDP_Bitread_Read (pReader, 1);
1165                                cc_type = BUDP_Bitread_Read (pReader, 2);
1166
1167                                (*pBytesParsed)++;
1168                                --userDataLength;
1169
1170                                /* Read the two bytes of closed caption data (16) */
1171                                cc_data_1 = BUDP_Bitread_Byte (pReader);
1172                                (*pBytesParsed)++;
1173                                --userDataLength;
1174                                cc_data_2 = BUDP_Bitread_Byte (pReader);
1175                                (*pBytesParsed)++;
1176                                --userDataLength;
1177
1178                                /* Store the data if warranted */
1179                                if (process_cc_data_flag && miscBits == 0x1F)
1180                                {
1181                                        pCCdata[*pcc_count].cc_valid = cc_valid;
1182                                        pCCdata[*pcc_count].seq.cc_type = cc_type;
1183                                        pCCdata[*pcc_count].cc_data_1 = cc_data_1;
1184                                        pCCdata[*pcc_count].cc_data_2 = cc_data_2;
1185
1186                                        /* Kludge */
1187                                        pCCdata[*pcc_count].line_offset = 11;
1188
1189                                        pCCdata[*pcc_count].format = BUDP_DCCparse_Format_SEI;
1190                                        (*pcc_count)++;
1191                                }
1192
1193                        }
1194
1195                        /* Read marker bits (8) */
1196                        miscBits = BUDP_Bitread_Byte (pReader);
1197                        if (miscBits != 0xFF)
1198                        {
1199                                return BERR_BUDP_PARSE_ERROR;
1200                        }
1201                        (*pBytesParsed)++;
1202                        --userDataLength;
1203                }
1204                else
1205                {
1206                        /* Skip over non-CC data */
1207                        if (user_data_code_length > 0)
1208                        {
1209                                for (index = 0 ; index < (user_data_code_length-1) ; ++index)
1210                                        BUDP_Bitread_Byte (pReader);
1211                                *pBytesParsed += (user_data_code_length-1);
1212                                userDataLength -= (user_data_code_length-1);
1213                        }
1214                        /* Programming note: within the above "if" clause, all instances of
1215                         * (user_data_code_length-1) could be replaced with
1216                         * user_data_code_length. But, I am trying to support older,
1217                         * non-compliant bitstreams along with compliant bitstreams. In
1218                         * this case, my strategy is to skip over the smaller number of
1219                         * bytes, and trust that in the case of a compliant bitstream, the
1220                         * next executing parser will manage to skip over the remaining
1221                         * single byte.
1222                         */
1223                }
1224        }
1225
1226        BUDP_SETFIELDSPARITY_SEI (pCCdata, *pcc_count, pUserdata_info);
1227
1228        return BERR_SUCCESS;
1229}
1230
1231/***************************************************************************
1232 * This function parses SEI user data.  It assumes that the userdata
1233 * startcode 0x000001B2 has just been read. This is the new format using
1234 * ATSC/53.
1235 */
1236static BERR_Code ParseSEIData2 (
1237        const BAVC_USERDATA_info*      pUserdata_info,
1238        BUDP_Bitread_Context* pReader,
1239        size_t                                   length,
1240        size_t*                  pBytesParsed,
1241        uint8_t*                 pcc_count,
1242        BUDP_DCCparse_ccdata* pCCdata
1243)
1244{
1245        uint8_t seiType;
1246        uint8_t userDataLength;
1247        uint8_t country_code;
1248        uint16_t manufacturers_code;
1249        BERR_Code eErr;
1250        size_t lBytesParsed = 0;
1251
1252        /* We must have at least one type byte and a length byte */
1253        if (length < 2)
1254        {   
1255                return BERR_BUDP_NO_DATA;;
1256        }
1257
1258        /* Read 8-bit type field */
1259        seiType = BUDP_Bitread_Byte (pReader);
1260        ++lBytesParsed;
1261        if (seiType != 0x04)
1262        {
1263                return BERR_BUDP_NO_DATA;;
1264        }
1265
1266        /* Read 8-bit length field */
1267        userDataLength = BUDP_Bitread_Byte (pReader);
1268        ++lBytesParsed;
1269
1270        /* A consistency check */
1271        if (userDataLength > (unsigned)(length - 2))
1272        {
1273                return BERR_BUDP_PARSE_ERROR;
1274        }
1275
1276        /* Prevent access violations */
1277        if (userDataLength < 3)
1278        {
1279                return BERR_BUDP_PARSE_ERROR;
1280        }
1281
1282        /* Read and ignore 8-bit country code */
1283        country_code = BUDP_Bitread_Byte (pReader);
1284        ++lBytesParsed;
1285        --userDataLength;
1286
1287        /* Read and ignore 16-bit provider code code */
1288        manufacturers_code  = BUDP_Bitread_Byte (pReader) << 8;
1289        manufacturers_code |= BUDP_Bitread_Byte (pReader);
1290        lBytesParsed += 2;
1291        userDataLength -= 2;
1292
1293        {
1294           BUDP_Bitread_Context stSavedReader = *pReader;
1295           unsigned iparser;
1296
1297           /* Try all the available parsers */
1298           for (iparser = 0 ; iparser < NUM_MPEG_PARSERS ; ++iparser)
1299           {
1300              *pReader = stSavedReader;
1301
1302              eErr = (*s_mpegParsers[iparser].parser) (
1303                 pUserdata_info, pReader, length - lBytesParsed,
1304                 pBytesParsed, pcc_count, pCCdata );
1305              switch (eErr)
1306              {
1307                 case BERR_SUCCESS:
1308                    /* Sarnoff compliance check */
1309                    if ((pUserdata_info->eUserDataType == BAVC_USERDATA_Type_eSeq)
1310                       ||
1311                       (pUserdata_info->eUserDataType == BAVC_USERDATA_Type_eGOP))
1312                    {
1313                       eErr = BERR_BUDP_SOURCE_CHECK;
1314                    }
1315                    /* fall into the next case */
1316                 case BERR_BUDP_PARSE_ERROR:
1317                    *pBytesParsed += *pBytesParsed;
1318                    BDBG_LEAVE(BUDP_DCCparse);
1319                    return eErr;
1320                    break;
1321                 case BERR_BUDP_NO_DATA:
1322                    break;
1323                 default:
1324                    /* Programming error */
1325                    BDBG_ASSERT (false);
1326                    break;
1327              }
1328           }
1329        }
1330
1331        *pBytesParsed += lBytesParsed;
1332       
1333        return eErr;
1334}
1335
1336/***************************************************************************
1337 * This function sets the topfield/bottomfield polarity for closed caption
1338 * data already extracted from the bitstream.  It uses the order * in which
1339 * the digital data is presented, and top_field_first.
1340 */
1341static void SetFieldsParity_NOCCTYPE (
1342        BUDP_DCCparse_ccdata* pCCdata,
1343        uint8_t                  cc_count,
1344        const BAVC_USERDATA_info*      pUserdata_info)
1345{
1346        bool top_field_first           = pUserdata_info->bTopFieldFirst;
1347        bool repeat_first_field        = pUserdata_info->bRepeatFirstField;
1348        BAVC_Polarity pictureStructure = pUserdata_info->eSourcePolarity;
1349        int icount;
1350
1351        /* TODO: consider the case where there is cc_valid==0 data. Is the icount
1352         * ----  handling correct?
1353         */
1354
1355        for (icount = 0 ; icount < cc_count ; ++icount)
1356        {
1357                /* Skip invalid data */
1358                if (pCCdata->cc_valid == 0)
1359                {
1360                        pCCdata->polarity = BAVC_Polarity_eFrame;
1361                        pCCdata->bIsAnalog = false;
1362                        ++pCCdata;
1363                        continue;
1364                }
1365
1366                /* This is the case of a (top or bottom) field picture */
1367                if ((pictureStructure == BAVC_Polarity_eTopField) ||
1368                    (pictureStructure == BAVC_Polarity_eBotField)   )
1369                {
1370                        pCCdata->polarity = pictureStructure;
1371                        pCCdata->bIsAnalog = true;
1372                        ++pCCdata;
1373                        continue;
1374                }
1375
1376                /* This is an MPEG syntax error.  Punt. */
1377                if (pictureStructure !=  BAVC_Polarity_eFrame)
1378                {
1379                        pCCdata->polarity = BAVC_Polarity_eFrame;
1380                        pCCdata->bIsAnalog = false;
1381                        ++pCCdata;
1382                        continue;
1383                }
1384
1385                /* This is an error.  Punt. */
1386                if (((icount > 2) && !repeat_first_field) ||
1387                    (icount > 3))
1388                {
1389                        pCCdata->polarity = BAVC_Polarity_eFrame;
1390                        pCCdata->bIsAnalog = false;
1391                        ++pCCdata;
1392                        continue;
1393                }
1394
1395                /* This is the normal case.
1396                We are not relying on pCCdata->seq.cc_type to have a correct value,
1397                therefore we just use the index position of the data. */
1398                if (cc_count == 1) {
1399                        pCCdata->polarity = BAVC_Polarity_eTopField;
1400                }
1401                else {
1402                        switch (icount&1)
1403                        {
1404                        case 0:
1405                                pCCdata->polarity = 
1406                                        (top_field_first ? 
1407                                                BAVC_Polarity_eTopField : BAVC_Polarity_eBotField);
1408                                break;
1409                        default: /*case 1:*/
1410                                pCCdata->polarity = 
1411                                        (top_field_first ?
1412                                                BAVC_Polarity_eBotField : BAVC_Polarity_eTopField);
1413                                break;
1414                        }
1415                }
1416                pCCdata->bIsAnalog = true;
1417                ++pCCdata;
1418        }
1419}
1420
1421/***************************************************************************
1422 * This function sets the topfield/bottomfield polarity for closed caption
1423 * data already extracted from the bitstream.  It relies on the field_number
1424 * attribute, and top_field_first.
1425 */
1426static void SetFieldsParity_FIELDNUMBER (
1427        BUDP_DCCparse_ccdata* pCCdata,
1428        uint8_t                  cc_count,
1429        const BAVC_USERDATA_info*      pUserdata_info)
1430{
1431        int icount;
1432        uint8_t field_number;
1433        bool top_field_first           = pUserdata_info->bTopFieldFirst;
1434        bool repeat_first_field        = pUserdata_info->bRepeatFirstField;
1435        BAVC_Polarity pictureStructure = pUserdata_info->eSourcePolarity;
1436
1437        for (icount = 0 ; icount < cc_count ; ++icount)
1438        {
1439                /* Skip invalid data */
1440                if (pCCdata->cc_valid == 0)
1441                {
1442                        pCCdata->polarity = BAVC_Polarity_eFrame;
1443                        pCCdata->bIsAnalog = false;
1444                        ++pCCdata;
1445                        continue;
1446                }
1447
1448                field_number = pCCdata->seq.field_number;
1449
1450                switch (pictureStructure)
1451                {
1452                case BAVC_Polarity_eTopField:
1453                        pCCdata->polarity = BAVC_Polarity_eTopField;
1454                        pCCdata->bIsAnalog = true;
1455                        break;
1456                case BAVC_Polarity_eBotField:
1457                        pCCdata->polarity = BAVC_Polarity_eBotField;
1458                        pCCdata->bIsAnalog = true;
1459                        break;
1460                case BAVC_Polarity_eFrame:
1461                        switch (field_number)
1462                        {
1463                        case 0:
1464                                /* Forbidden!  Punt! */
1465                                pCCdata->polarity = BAVC_Polarity_eFrame;
1466                                pCCdata->bIsAnalog = false;
1467                                break;
1468                        case 1:
1469                                pCCdata->polarity = 
1470                                        (top_field_first ? 
1471                                                BAVC_Polarity_eTopField : BAVC_Polarity_eBotField);
1472                                pCCdata->bIsAnalog = true;
1473                                break;
1474                        case 2:
1475                                pCCdata->polarity = 
1476                                        (top_field_first ? 
1477                                                BAVC_Polarity_eBotField : BAVC_Polarity_eTopField);
1478                                pCCdata->bIsAnalog = true;
1479                                break;
1480                        case 3:
1481                                if (repeat_first_field)
1482                                {
1483                                        pCCdata->polarity = 
1484                                                (top_field_first ? 
1485                                                        BAVC_Polarity_eTopField : BAVC_Polarity_eBotField);
1486                                        pCCdata->bIsAnalog = true;
1487                                }
1488                                else
1489                                {
1490                                        /* Makes no sense!  Punt! */
1491                                        pCCdata->polarity = BAVC_Polarity_eFrame;
1492                                        pCCdata->bIsAnalog = false;
1493                                }
1494                                break;
1495                        }
1496                        break;
1497                default:
1498                        /* No other picture types to consider!  Punt! */
1499                        pCCdata->polarity = BAVC_Polarity_eFrame;
1500                        pCCdata->bIsAnalog = false;
1501                        break;
1502                }
1503                ++pCCdata;
1504        }
1505}
1506
1507/***************************************************************************
1508 * This function sets the topfield/bottomfield polarity for closed caption
1509 * data already extracted from the bitstream.  It uses the cc_type attribute,
1510 * and top_field_first.
1511 */
1512static void SetFieldsParity_TFF (
1513        BUDP_DCCparse_ccdata* pCCdata,
1514        uint8_t                  cc_count,
1515        const BAVC_USERDATA_info*      pUserdata_info)
1516{
1517        bool top_field_first           = pUserdata_info->bTopFieldFirst;
1518        bool repeat_first_field        = pUserdata_info->bRepeatFirstField;
1519        BAVC_Polarity pictureStructure = pUserdata_info->eSourcePolarity;
1520        int icount;
1521
1522        for (icount = 0 ; icount < cc_count ; ++icount)
1523        {
1524                /* Skip invalid data */
1525                if (pCCdata->cc_valid == 0)
1526                {
1527                        pCCdata->polarity = BAVC_Polarity_eFrame;
1528                        pCCdata->bIsAnalog = false;
1529                        ++pCCdata;
1530                        continue;
1531                }
1532
1533                /* This is the case of a (top or bottom) field picture */
1534                if ((pictureStructure == BAVC_Polarity_eTopField) ||
1535                    (pictureStructure == BAVC_Polarity_eBotField)   )
1536                {
1537                        switch (pCCdata->seq.cc_type)
1538                        {
1539                        case 0:
1540                        case 1:
1541                                /* Top or bottom field, according to picture structure */
1542                                pCCdata->polarity = pictureStructure;
1543                                pCCdata->bIsAnalog = true;
1544                                break;
1545                        default:
1546                                /* Punt! */
1547                                pCCdata->polarity = BAVC_Polarity_eFrame;
1548                                pCCdata->bIsAnalog = false;
1549                                break;
1550                        }
1551                        ++pCCdata;
1552                        continue;
1553                }
1554
1555                /* This is an MPEG syntax error.  Punt. */
1556                if (pictureStructure !=  BAVC_Polarity_eFrame)
1557                {
1558                        pCCdata->polarity = BAVC_Polarity_eFrame;
1559                        pCCdata->bIsAnalog = false;
1560                        ++pCCdata;
1561                        continue;
1562                }
1563
1564                /* This is an error.  Punt. */
1565                if (((icount > 2) && !repeat_first_field) ||
1566                    (icount > 3))
1567                {
1568                        pCCdata->polarity = BAVC_Polarity_eFrame;
1569                        pCCdata->bIsAnalog = false;
1570                        ++pCCdata;
1571                        continue;
1572                }
1573
1574                /* This is the normal case */
1575                switch (pCCdata->seq.cc_type)
1576                {
1577                case 0:
1578                        pCCdata->polarity = 
1579                                (top_field_first ? 
1580                                        BAVC_Polarity_eTopField : BAVC_Polarity_eBotField);
1581                        pCCdata->bIsAnalog = true;
1582                        break;
1583                case 1:
1584                        pCCdata->polarity = 
1585                                (top_field_first ?
1586                                        BAVC_Polarity_eBotField : BAVC_Polarity_eTopField);
1587                        pCCdata->bIsAnalog = true;
1588                        break;
1589                default:
1590                        /* Punt! */
1591                        pCCdata->polarity = BAVC_Polarity_eFrame;
1592                        pCCdata->bIsAnalog = false;
1593                        break;
1594                }
1595                ++pCCdata;
1596        }
1597}
1598
1599/***************************************************************************
1600 * This function sets the topfield/bottomfield polarity for closed caption
1601 * data already extracted from the bitstream.  It uses only the cc_type
1602 * attribute, and NOT top_field_first.
1603 */
1604static void SetFieldsParity_SIMPLE (
1605        BUDP_DCCparse_ccdata* pCCdata,
1606        uint8_t                  cc_count,
1607        const BAVC_USERDATA_info*      pUserdata_info)
1608{
1609        bool repeat_first_field        = pUserdata_info->bRepeatFirstField;
1610        BAVC_Polarity pictureStructure = pUserdata_info->eSourcePolarity;
1611        int icount;
1612
1613        for (icount = 0 ; icount < cc_count ; ++icount)
1614        {
1615                /* Skip invalid data */
1616                if (pCCdata->cc_valid == 0)
1617                {
1618                        pCCdata->polarity = BAVC_Polarity_eFrame;
1619                        pCCdata->bIsAnalog = false;
1620                        ++pCCdata;
1621                        continue;
1622                }
1623
1624                /* EIA-708-B has an odd restriction in the case of field pictures */
1625                if (pictureStructure == BAVC_Polarity_eTopField)
1626                {
1627                        if (pCCdata->seq.cc_type == 0) 
1628                        {
1629                                pCCdata->polarity = BAVC_Polarity_eFrame;
1630                                pCCdata->bIsAnalog = false;
1631                                ++pCCdata;
1632                                continue;
1633                        }
1634                }
1635                else if (pictureStructure == BAVC_Polarity_eBotField)
1636                {
1637                        if (pCCdata->seq.cc_type == 1)
1638                        {
1639                                pCCdata->polarity = BAVC_Polarity_eFrame;
1640                                pCCdata->bIsAnalog = false;
1641                                ++pCCdata;
1642                                continue;
1643                        }
1644                }
1645
1646                /* This is an MPEG syntax error.  Punt. */
1647                else if (pictureStructure !=  BAVC_Polarity_eFrame)
1648                {
1649                        pCCdata->polarity = BAVC_Polarity_eFrame;
1650                        pCCdata->bIsAnalog = false;
1651                        ++pCCdata;
1652                        continue;
1653                }
1654
1655                /* This is an error.  Punt. */
1656                if (((icount > 2) && !repeat_first_field) ||
1657                    (icount > 3))
1658                {
1659                        pCCdata->polarity = BAVC_Polarity_eFrame;
1660                        pCCdata->bIsAnalog = false;
1661                        ++pCCdata;
1662                        continue;
1663                }
1664
1665                /* This is the normal case. A nice, ordinary frame picture. */
1666                switch (pCCdata->seq.cc_type)
1667                {
1668                case 0:
1669                        pCCdata->polarity = BAVC_Polarity_eTopField;
1670                        pCCdata->bIsAnalog = true;
1671                        break;
1672                case 1:
1673                        pCCdata->polarity = BAVC_Polarity_eBotField;
1674                        pCCdata->bIsAnalog = true;
1675                        break;
1676                default:
1677                        /* Punt! */
1678                        pCCdata->polarity = BAVC_Polarity_eFrame;
1679                        pCCdata->bIsAnalog = false;
1680                        break;
1681                }
1682                ++pCCdata;
1683        }
1684}
1685
1686/***************************************************************************
1687 * This function sets the topfield/bottomfield polarity for closed caption
1688 * data already extracted from the bitstream.  It only uses cc_type. It is
1689 * even more simple than SetFieldsParity_SIMPLE, and is for use with closed
1690 * caption data extracted from SEI.
1691 */
1692static void SetFieldsParity_SEI (
1693        BUDP_DCCparse_ccdata* pCCdata,
1694        uint8_t                  cc_count,
1695        const BAVC_USERDATA_info*      pUserdata_info)
1696{
1697        BAVC_Polarity pictureStructure = pUserdata_info->eSourcePolarity;
1698        int icount;
1699
1700        for (icount = 0 ; icount < cc_count ; ++icount)
1701        {
1702                /* Skip invalid data */
1703                if (pCCdata->cc_valid == 0)
1704                {
1705                        pCCdata->polarity = BAVC_Polarity_eFrame;
1706                        pCCdata->bIsAnalog = false;
1707                        ++pCCdata;
1708                        continue;
1709                }
1710
1711                /* This is an MPEG syntax error.  Punt. */
1712                if (pictureStructure != BAVC_Polarity_eTopField &&
1713                    pictureStructure != BAVC_Polarity_eBotField &&
1714                    pictureStructure != BAVC_Polarity_eFrame)
1715                {
1716                        BDBG_ERR(("Unrecognized picture structure received (%d)", 
1717                                pictureStructure));
1718                        pCCdata->polarity = BAVC_Polarity_eFrame;
1719                        pCCdata->bIsAnalog = false;
1720                        ++pCCdata;
1721                        continue;
1722                }
1723
1724                /* Normal case */
1725                switch (pCCdata->seq.cc_type)
1726                {
1727                case 0:
1728                        pCCdata->polarity = BAVC_Polarity_eTopField;
1729                        pCCdata->bIsAnalog = true;
1730                        break;
1731                case 1:
1732                        pCCdata->polarity = BAVC_Polarity_eBotField;
1733                        pCCdata->bIsAnalog = true;
1734                        break;
1735                default:
1736                        /* Punt! */
1737                        pCCdata->polarity = BAVC_Polarity_eFrame;
1738                        pCCdata->bIsAnalog = false;
1739                        break;
1740                }
1741                ++pCCdata;
1742        }
1743}
1744
1745/***************************************************************************
1746 * This function reverses the order of bits in a byte.
1747*/
1748static int swap_bits(int src)
1749{
1750        int result;
1751        int i;
1752
1753        for (result = 0, i = 0; i < 8; i++) 
1754        {
1755                result = (result << 1) | (src & 1);
1756                src >>= 1;
1757        }
1758        return result;
1759}
1760
1761/***************************************************************************
1762 * This function serves to get rid of a compiler warning
1763*/
1764void BUDP_P_Quiet_Compiler (
1765        BUDP_DCCparse_ccdata* pCCdata,
1766        uint8_t                        cc_count,
1767        const BAVC_USERDATA_info*      pUserdata_info)
1768{
1769        SetFieldsParity_SIMPLE      ( pCCdata, cc_count, pUserdata_info);
1770        SetFieldsParity_TFF         ( pCCdata, cc_count, pUserdata_info);
1771        SetFieldsParity_NOCCTYPE    ( pCCdata, cc_count, pUserdata_info);
1772        SetFieldsParity_FIELDNUMBER ( pCCdata, cc_count, pUserdata_info);
1773        SetFieldsParity_SEI         ( pCCdata, cc_count, pUserdata_info);
1774}
1775
1776#ifdef BUDP_P_GETUD_DUMP
1777static void dump_getud (
1778        const BAVC_USERDATA_info* pUserdata_info, size_t offset)
1779{
1780        unsigned int iByte;
1781        static FILE* fd = NULL;
1782        static unsigned int nPicture;
1783        uint8_t* userdata = (uint8_t*)(pUserdata_info->pUserDataBuffer) + offset;
1784        size_t   length   = pUserdata_info->ui32UserDataBufSize - offset;
1785
1786        /* Initialization */
1787        if (fd == NULL)
1788        {
1789                if ((fd = fopen (BUDP_P_Getud_Filename, "w")) == 0)
1790                {
1791                        fprintf (stderr, "ERROR: could not open %s for debug output\n",
1792                                BUDP_P_Getud_Filename);
1793                        return;
1794                }
1795                fprintf (fd, "getud output format version 1\n");
1796                nPicture = 0;
1797        }
1798
1799        fprintf (fd, "\nPic %u LOC %06lx TR %u\n", ++nPicture, 0UL, 0U);
1800        fprintf (fd, "PS %d TFF %d RFF %d\n",
1801                pUserdata_info->eSourcePolarity,
1802                pUserdata_info->bTopFieldFirst,
1803                pUserdata_info->bRepeatFirstField);
1804        fprintf (fd, "UDBYTES %u\n", length);
1805    for (iByte = 0 ; iByte < length ; ++iByte)
1806    {
1807        fprintf (fd, "%02x", userdata[iByte]);
1808        if ((iByte % 16) == 15)
1809            putc ('\n', fd);
1810        else
1811            putc (' ', fd);
1812    }
1813    if ((iByte % 16) != 15)
1814        putc ('\n', fd);
1815}
1816#endif
Note: See TracBrowser for help on using the repository browser.