source: svn/newcon3bcm2_21bu/magnum/commonutils/udp/budp_dccparse_divicom.c @ 22

Last change on this file since 22 was 22, checked in by phkim, 11 years ago
  1. phkim
  2. newcon3sk 를 kctv 로 브랜치 함
  • Property svn:executable set to *
File size: 9.4 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2003-2010, 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_divicom.c $
11 * $brcm_Revision: Hydra_Software_Devel/2 $
12 * $brcm_Date: 10/28/10 3:58p $
13 *
14 * Module Description:
15 *
16 * Revision History:
17 *
18 * $brcm_Log: /magnum/commonutils/udp/budp_dccparse_divicom.c $
19 *
20 * Hydra_Software_Devel/2   10/28/10 3:58p darnstein
21 * SW3548-2364: trivial implementation of _isr functions for parsing.
22 *
23 * Hydra_Software_Devel/1   7/27/10 5:06p darnstein
24 * SW3548-3022: userdata parsing software.
25 *
26 ***************************************************************************/
27
28/* For debugging */
29/* #define BUDP_P_GETUD_DUMP 1 */
30#ifdef BUDP_P_GETUD_DUMP
31static const char* BUDP_P_Getud_Filename = "userdata.getud";
32#include <stdio.h>
33#endif
34
35#include "bstd.h"
36#include "bavc.h"
37#include "bdbg.h"
38#include "budp.h"
39#include "budp_bitread.h"
40#include "budp_dccparse.h"
41
42BDBG_MODULE(BUDP);
43
44
45/***************************************************************************
46* Forward declarations of static (private) functions
47***************************************************************************/
48
49static BERR_Code ParseDivicomData (
50        const BAVC_USERDATA_info*      pUserdata_info,
51        BUDP_Bitread_Context* pReader,
52        size_t                                   length,
53        size_t*                  pBytesParsed,
54        uint8_t*                 pcc_count,
55        BUDP_DCCparse_ccdata* pCCdata
56);
57static size_t FindMpegUserdataStart (
58        BUDP_Bitread_Context* pREader, size_t length);
59
60#ifdef BUDP_P_GETUD_DUMP
61static void dump_getud (
62        const BAVC_USERDATA_info* pUserdata_info, size_t offset);
63#endif
64
65/***************************************************************************
66* Static data (tables, etc.)
67***************************************************************************/
68
69static const bool bByteswap = (BSTD_CPU_ENDIAN == BSTD_ENDIAN_LITTLE);
70
71/***************************************************************************
72* Implementation of "BUDP_DCCparse_" API functions
73***************************************************************************/
74
75
76/***************************************************************************
77 *
78 */
79BERR_Code BUDP_DCCparse_Divicom_isr ( 
80        const BAVC_USERDATA_info*      pUserdata_info, 
81        size_t                   offset, 
82        size_t*                  pBytesParsed,
83        uint8_t*                 pcc_count,
84        BUDP_DCCparse_ccdata* pCCdata
85)
86{
87        size_t bytesParsedSub;
88        size_t length;
89        uint8_t* userdata;
90        BERR_Code eErr;
91        BUDP_Bitread_Context reader; 
92
93        BDBG_ENTER(BUDP_DCCparse_Divicom);
94
95        /* Check for obvious errors from user */
96        if ((pUserdata_info == 0x0) ||
97            (pBytesParsed   == 0x0) ||
98            (pcc_count      == 0x0) ||
99            (pCCdata        == 0x0)   )
100        {
101                return BERR_INVALID_PARAMETER;
102        }
103
104        /* Programming note:  all function parameters are now validated */
105
106#ifdef BUDP_P_GETUD_DUMP
107        dump_getud (pUserdata_info, offset);
108#endif
109
110        /* Take care of a special case */
111        userdata = (uint8_t*)(pUserdata_info->pUserDataBuffer) + offset;
112        length   = pUserdata_info->ui32UserDataBufSize - offset;
113        if (length < 4)
114        {
115                *pBytesParsed = length;
116                return BERR_BUDP_NO_DATA;
117        }
118
119        /* Prepare to play with bits */
120        BUDP_Bitread_Init (&reader, bByteswap, userdata);
121
122        /* jump past the first MPEG userdata start code */
123        bytesParsedSub = FindMpegUserdataStart (&reader, length);
124        *pBytesParsed = bytesParsedSub;
125        length -= bytesParsedSub;
126
127        /* If we did not find a start code, bail out now */
128        if (length == 0)
129        {
130                return BERR_BUDP_NO_DATA;
131        }
132
133        eErr = ParseDivicomData (
134                pUserdata_info, &reader, length, 
135                &bytesParsedSub, pcc_count, pCCdata);
136        switch (eErr)
137        {
138        case BERR_SUCCESS:
139                /* fall into the next case */
140        case BERR_BUDP_PARSE_ERROR:
141                *pBytesParsed += bytesParsedSub;
142                BDBG_LEAVE(BUDP_DCCparse_Divicom);
143                return eErr;
144                break;
145        case BERR_BUDP_NO_DATA:
146                break;
147        default:
148                /* Programming error */
149                BDBG_ASSERT (false);
150                break;
151        }
152
153        /* If we did not find a start code, bail out now */
154        if (length == 0)
155        {
156                return BERR_BUDP_NO_DATA;
157        }
158
159        /* No userdata was found */
160        BDBG_LEAVE(BUDP_DCCparse_Divicom);
161        return BERR_BUDP_NO_DATA;
162}
163
164/***************************************************************************
165* Private functions
166***************************************************************************/
167
168/***************************************************************************
169 * This function finds the next userdata startcode 0x000001B2.  It
170 * indicates the byte following this startcode by its return value.
171 * If no startcode was found, it simply returns the length of the
172 * input data.
173 */
174static size_t FindMpegUserdataStart (
175        BUDP_Bitread_Context* pReader, size_t length)
176{
177    size_t count = 0;
178        uint8_t saved[4];
179
180        /* Special case (failure) */
181        if (length < 4)
182                return length;
183
184        /* Initialize */
185        saved[1] = BUDP_Bitread_Byte (pReader);
186        saved[2] = BUDP_Bitread_Byte (pReader);
187        saved[3] = BUDP_Bitread_Byte (pReader);
188
189        while (length >= 4)
190        { 
191                /* Read in another byte */
192                saved[0] = saved[1];
193                saved[1] = saved[2];
194                saved[2] = saved[3];
195                saved[3] = BUDP_Bitread_Byte (pReader);
196
197                if ((saved[0] == 0x00) &&
198                    (saved[1] == 0x00) &&
199                        (saved[2] == 0x01) &&
200                        (saved[3] == 0xB2)    ) 
201                {
202                        /* Found it! */
203                        break;
204                }
205
206                /* proceed to the next byte */
207                --length;
208                ++count;
209        }
210
211        if (length >= 4)
212        {
213                /* found the pattern before the end of stream */   
214                return count + 4;
215        }
216        else
217        {
218                /* Didn't find any start code */
219                return count + 3;
220        }
221}
222
223/***************************************************************************
224 * This function parses Divicom data.  It assumes that the userdata
225 * startcode 0x000001B2 has just been read.
226 */
227static BERR_Code ParseDivicomData (
228        const BAVC_USERDATA_info*      pUserdata_info,
229        BUDP_Bitread_Context* pReader,
230        size_t                                   length,
231        size_t*                  pBytesParsed,
232        uint8_t*                 pcc_count,
233        BUDP_DCCparse_ccdata* pCCdata
234)
235{
236        unsigned int cc_count;
237        unsigned int vbi_field_type;
238        unsigned int icount;
239        int data_found;
240
241        BSTD_UNUSED (pUserdata_info);
242
243        /* Start counting */
244        *pcc_count = 0;
245        *pBytesParsed = 0;
246        data_found = 0;
247
248        /* Start travelling pointer into data */
249        if (length < 2)
250        {   
251                return BERR_BUDP_PARSE_ERROR;
252        }
253
254        /* Dig out first count of cc data pairs,  and field type */
255        cc_count       = BUDP_Bitread_Byte (pReader);
256        vbi_field_type = BUDP_Bitread_Byte (pReader);
257
258        /* It seems that a zero cc_count marks the end of data. This is not
259         * documented */
260        while (cc_count != 0)
261        {
262                /* Only a few legal values for cc_count and vbi_field_type */
263                if ((cc_count != 2) && (cc_count != 4))
264                {
265                        return BERR_BUDP_PARSE_ERROR;
266                }
267                if ((vbi_field_type != 0x09) && (vbi_field_type != 0x0a))
268                {
269                        return BERR_BUDP_PARSE_ERROR;
270                }
271
272                /* Account for cc_count and vbi_field_type bytes */
273                length -= 2;
274                *pBytesParsed += 2;
275
276                /* Account for closed caption bytes about to be parsed */
277                if (length < cc_count)
278                {   
279                        /* Packet too short */
280                        return BERR_BUDP_PARSE_ERROR;
281                }
282                length -= cc_count;
283                *pBytesParsed += cc_count;
284
285                /* Dig out the closed caption data pairs */
286                for (icount = 0 ; icount < cc_count/2 ; icount+=2)
287                {
288                        /* Kludge */
289                        pCCdata[data_found].line_offset = 11;
290                        pCCdata[data_found].cc_valid    =  1;
291                        pCCdata[data_found].cc_priority =  0;
292
293                        /* Here is the closed caption data, finally. */
294                        pCCdata[data_found].cc_data_1 = 
295                                BUDP_Bitread_Byte (pReader);
296                        pCCdata[data_found].cc_data_2 = 
297                                BUDP_Bitread_Byte (pReader);
298                        pCCdata[data_found].format = BUDP_DCCparse_Format_Divicom;
299                        pCCdata[data_found].bIsAnalog = true;
300
301                        /* Parity of extracted data is determined by vbi_field_type */
302                        if (vbi_field_type == 0x09) 
303                        {
304                                pCCdata[data_found].polarity = BAVC_Polarity_eTopField;
305                                pCCdata[data_found].seq.cc_type = 0;
306                        }
307                        else
308                        {
309                                pCCdata[data_found].polarity = BAVC_Polarity_eBotField;
310                                pCCdata[data_found].seq.cc_type = 1;
311                        }
312
313                        /* Update count of items written to output data */
314                        ++data_found;
315                }
316
317                /* Dig out next cc_count */
318                cc_count       = BUDP_Bitread_Byte (pReader);
319                vbi_field_type = BUDP_Bitread_Byte (pReader);
320        }
321
322        *pcc_count = data_found;
323        return BERR_SUCCESS;
324}
325
326#ifdef BUDP_P_GETUD_DUMP
327static void dump_getud (
328        const BAVC_USERDATA_info* pUserdata_info, size_t offset)
329{
330        unsigned int iByte;
331        static FILE* fd = NULL;
332        static unsigned int nPicture;
333        uint8_t* userdata = (uint8_t*)(pUserdata_info->pUserDataBuffer) + offset;
334        size_t   length   = pUserdata_info->ui32UserDataBufSize - offset;
335
336        /* Initialization */
337        if (fd == NULL)
338        {
339                if ((fd = fopen (BUDP_P_Getud_Filename, "w")) == 0)
340                {
341                        fprintf (stderr, "ERROR: could not open %s for debug output\n",
342                                BUDP_P_Getud_Filename);
343                        return;
344                }
345                fprintf (fd, "getud output format version 1\n");
346                nPicture = 0;
347        }
348
349        fprintf (fd, "\nPic %u LOC %06lx TR %u\n", ++nPicture, 0UL, 0U);
350        fprintf (fd, "PS %d TFF %d RFF %d\n",
351                pUserdata_info->eSourcePolarity,
352                pUserdata_info->bTopFieldFirst,
353                pUserdata_info->bRepeatFirstField);
354        fprintf (fd, "UDBYTES %u\n", length);
355    for (iByte = 0 ; iByte < length ; ++iByte)
356    {
357        fprintf (fd, "%02x", userdata[iByte]);
358        if ((iByte % 16) == 15)
359            putc ('\n', fd);
360        else
361            putc (' ', fd);
362    }
363    if ((iByte % 16) != 15)
364        putc ('\n', fd);
365}
366#endif
Note: See TracBrowser for help on using the repository browser.