source: svn/newcon3bcm2_21bu/dst/dlib/src/si/DLIB_PSI_Parser.c

Last change on this file was 76, checked in by megakiss, 10 years ago

1W 대기전력을 만족시키기 위하여 POWEROFF시 튜너를 Standby 상태로 함

  • Property svn:executable set to *
File size: 20.0 KB
Line 
1/**
2        @file
3                DLIB_PSI_Parser.c
4
5        @brief
6*/
7
8
9#include "DHL_DBG.h"
10#include "DHL_UTL.h"
11
12#include "DLIB_BitOp.h"
13#include "DLIB_PSI.h"
14#include "DLIB_PSI_Parser.h"
15
16
17
18DHL_MODULE("!psi_parser", 0);
19
20#if COMMENT
21____Config____(){}
22#endif
23
24/*
25#define ENABLE_SYNTAX_CHECKING
26*/
27#if SUPPORT_DST_PLATFORM
28#define MEM_LIMIT                               0x00008000      /* BK: 0x00004000 16k => 0x00008000 32k*/
29#else
30#define MEM_LIMIT                               0x00004000      /* 16k */
31#endif
32
33
34
35
36
37#if 1
38// cafrii 070423 enable
39// ¹®Á¦ÀÇ streamµé¿¡ ´ëÇÑ µð¹ö±ë Â÷¿ø¿¡¼­ enable..
40#define FORMATWARNING(str) if (1) { DHL_OS_Printf("!! Format Warning: %s\n",str); \
41         err = DHL_FAIL; }
42#define FORMATWARNING2(s1,s2) if (1) { DHL_OS_Printf("!! Format Warning: %s %s\n", \
43        (s1),(s2)); err = DHL_FAIL; }
44#define FORMATWARNINGD(s1,d1) if (1) { DHL_OS_Printf("!! Format Warning: %s %d\n", \
45        (s1),(INT32)(d1)); err = DHL_FAIL; }
46#else
47#define FORMATWARNING(str) {err = DHL_FAIL;}
48#define FORMATWARNING2(s1,s2) {err = DHL_FAIL;}
49#define FORMATWARNINGD(s1,d1) {err = DHL_FAIL;}
50#endif
51
52
53
54#define SECTION_TID           0              /* TID index                    */
55#define SECTION_LEN_HI        1              /* length hi index              */
56#define SECTION_LEN_LO        2              /* length lo index              */
57#define SECTION_TID_EXT_HI        3              /* Table ID extension high index*/
58#define SECTION_TID_EXT_LO    4              /* Table ID extension low index */
59#define SECTION_VERSION       5              /* version number index         */
60#define SECTION_NUM           6              /* section number index         */
61#define SECTION_NUM_LAST      7              /* last section number index    */
62#define SECTION_HEADER_LENGTH 8                          /* number of bytes in section header */
63
64#define SECTION_LEN_MASK      0x0FFF         /* length bit mask              */
65#define SECTION_VERSION_MASK  0x3E           /* version number bit mask      */
66#define SECTION_VERSION_SHIFT 1                  /* version number bit shift     */
67#define SECTION_CNI_MASK      0x01           /* current next indicator mask  */
68
69#define PID_MASK                          0x1FFF                 /* Mask for various places a PID is used */
70
71
72/*
73        PMT/PAT/SIT macro definitions
74        FLAT_PSI_xxxx
75*/
76#define FLAT_PSI_MAX_SECTION_SIZE 1024           /* maximum size of PAT, PMT, or SIT section (including 3-byte header) */
77       
78#define PAT_SECTION_HEADER_LENGTH SECTION_HEADER_LENGTH /* minimum number of bytes in a PAT section (header length) */
79#define PMT_SECTION_HEADER_LENGTH 12             /* minimum number of bytes in a PMT section (header length) */
80
81#define PAT_PRGM_INFO_START      8               /* Program info (descriptors) start index */
82
83#define PAT_ENTRY_SIZE  4                                        /* number of bytes per PAT entry */
84
85#define PMT_PCR_PID_HI        8              /* PCR_PID hi byte index */
86#define PMT_PCR_PID_LO        9              /* PCR_PID lo byte index */
87#define PMT_PRGM_INFO_LEN_HI 10              /* Program info length hi byte index */
88#define PMT_PRGM_INFO_LEN_LO 11              /* Program info length lo byte index */
89#define PMT_PRGM_INFO_START      12              /* Program info (descriptors) start index */
90
91#define PCR_PID_MASK_HI       0x1F00         /* mask for high bits of PCR PID */
92#define PCR_PID_MASK_LO       0x00FF         /* mask for low bits of PCR PID */
93
94
95#if COMMENT
96____Types____(){}
97#endif
98
99
100
101
102#if COMMENT
103____Variables____(){}
104#endif
105
106
107
108
109#if COMMENT
110____Parse____(){}
111#endif
112
113static DHL_RESULT parse_video_stream_descriptor( UINT8* p, 
114                                                                        memId_t memId,
115                                                                        VideoStreamDescriptor **descripPtr)
116{
117        bitBuffer_t                             tBits;
118        bitBufferPtr_t                  bits = &tBits;
119        UINT8                           length;
120        DHL_RESULT                      err = DHL_OK;
121
122
123        DHL_ASSERT((p != NULL), "parse_video_stream_descriptor():bad parameter");
124        DHL_ASSERT((*p == video_stream_tag), "Bad descriptor tag.\n");
125
126        length = p[1];
127
128        bitBufferInitialize(bits,p+2,length);
129
130        /* create the descriptor memory */
131        *descripPtr = memChainAlloc(memId,sizeof(VideoStreamDescriptor));
132        if (*descripPtr == NULL) {
133                err = DHL_FAIL_OUT_OF_MEMORY;
134                goto ParseDescriptorExit;
135        }
136
137        (*descripPtr)->multiple_frame_rate_flag         = bitBufferGetBits(bits,1);
138        (*descripPtr)->frame_rate_code                  = (MPEG_FRAME_RATE) bitBufferGetBits(bits,4);
139        (*descripPtr)->MPEG_1_only_flag                 = bitBufferGetBits(bits,1);
140        (*descripPtr)->constrained_parameter_flag               = bitBufferGetBits(bits,1);
141        (*descripPtr)->still_picture_flag                       = bitBufferGetBits(bits,1);
142        if ((*descripPtr)->MPEG_1_only_flag == 0) {
143                (*descripPtr)->profile_and_level_indication     = bitBufferGetBits(bits,8);
144                (*descripPtr)->chroma_format                    = (MPEG_CHROMA_FORMAT) bitBufferGetBits(bits,2);
145                (*descripPtr)->frame_rate_extension_flag                = bitBufferGetBits(bits,1);
146                bitBufferSkipBits(bits,3);      /* reserved */
147        }
148
149
150ParseDescriptorExit:
151        return (err);
152}
153
154
155DHL_RESULT ParsePAT(const tDHL_PSI_DataArray *desc, MPEG_PAT **returnPat)
156{       
157        DHL_RESULT err = DHL_OK;
158        int i, j, k;
159        int numPrograms;
160        int slots;
161        int index;
162        const UINT8 *p;
163        int len;
164        int program_number;
165        MPEG_PAT *pat = NULL;
166        int version_number;
167        int transport_stream_id;
168        BOOLEAN current_next_indicator;
169        int pid;
170        memId_t                 memId = NULL;
171        memChainSetup_t         memSetup = {MEM_LIMIT,NULL,NULL};
172       
173        if (!desc || desc->numSections < 1) {
174                err = DHL_FAIL_INVALID_PARAM;
175                goto ParseExit;
176        }
177        numPrograms = 0;
178        /*
179         * First pass, we verify section syntax and count the number of programs
180         */
181        for (i = 0; i < desc->numSections; ++i) {
182                p = desc->sectPtr[i];
183                DHL_ASSERT(p != NULL, "ParsePAT: NULL section");
184                if (p[SECTION_TID] != PROGRAM_ASSOCIATION_SECTION) {
185                        /*
186                         * This thing isn't a PAT. Stop right here.
187                         */
188                        FORMATWARNING("PAT: Bad table ID.");
189                        err = DHL_FAIL_BAD_FORMAT;
190                        goto ParseExit;
191                }
192                if ((p[SECTION_LEN_HI] & 0x80) != 0x80) {
193                        FORMATWARNING("PAT: section_syntax_indicator not set");
194                }
195                if ((p[SECTION_LEN_HI] & 0x40) != 0x00) {
196                        FORMATWARNING("PAT: private_indicator set");
197                }
198                len = (((p[SECTION_LEN_HI] & 0x0F) << 8) | p[SECTION_LEN_LO]) + 3;
199                DHL_ASSERT(i == p[SECTION_NUM],"ParsePAT: bad section number");
200                if (i > p[SECTION_NUM_LAST]) {
201                        FORMATWARNING("PAT: last_section_number > section_number");
202                }
203                /*
204                 * The PAT has a fixed number of bytes in its main loop with no
205                 * descriptors. We have the standard 8 byte header and the trailing
206                 * 4 byte CRC. The rest should be an integral number of programs.
207                 */
208                if (len < 16 || (len - 12) % 4 != 0) {
209                        FORMATWARNING("PAT: Inappropriate section length");
210                }
211                slots = (len - 12) / 4;
212                p += SECTION_HEADER_LENGTH;
213                for (j = 0; j < slots; ++j, p += 4) {
214                        program_number = (p[0] << 8) + p[1];
215                        if (program_number != 0) {
216                                numPrograms++;
217                        }
218                }
219        }
220        /*
221         * At this point, numPrograms has the number of programs, which we can
222         * base the size of the PAT from.
223         */
224        /* create the memChain */
225        err = memChainCreate(&memId,&memSetup);
226        if (err) {
227                goto ParseExit;
228        }
229
230        pat = (MPEG_PAT *)((memId_t *)(memChainAlloc(memId,sizeof(MPEG_PAT)+sizeof(memId_t))) + 1);
231        checkMemoryError(pat);
232
233        pat->programs = memChainAlloc(memId,sizeof(MPEG_PAT_program)*numPrograms);
234        checkMemoryError(pat->programs);
235
236        pat->section_number = 0;
237        pat->last_section_number = 0;
238        pat->isWholePAT = TRUE;
239
240        /*
241         * Second pass, we fill in the table.
242         * We assume that everything we verified or warned about above is still
243         * true. We already bailed out on fatal errors
244         */
245        index = 0;
246        for (i = 0; i < desc->numSections; ++i) {
247                p = desc->sectPtr[i];
248                len = (((p[SECTION_LEN_HI] & 0x0F) << 8) | p[SECTION_LEN_LO]) + 3;
249               
250                transport_stream_id = ((p[SECTION_TID_EXT_HI] << 8) | 
251                                                                p[SECTION_TID_EXT_LO]);
252                version_number = (p[SECTION_VERSION] & SECTION_VERSION_MASK) >> 
253                                                        SECTION_VERSION_SHIFT;
254                current_next_indicator = (p[SECTION_VERSION] & SECTION_CNI_MASK) != 0;
255
256                if (i == 0) {
257                        pat->transport_stream_id = transport_stream_id;
258                        pat->version_number = version_number;
259                        pat->current_next_indicator = current_next_indicator;
260                }
261                else {
262                        if (pat->transport_stream_id != transport_stream_id) {
263                                FORMATWARNING("PAT: Inconsistent transport_stream_id");
264                        }
265                        DHL_ASSERT(pat->version_number == version_number,
266                                "ParsePAT: inconsistent version_number");
267                        DHL_ASSERT(pat->current_next_indicator == current_next_indicator,
268                                "ParsePAT: inconsistent current_next_indicator");
269                }
270                slots = (len - 12) / 4;
271                p += SECTION_HEADER_LENGTH;
272                for (j = 0; j < slots; ++j, p += 4) {
273                        program_number = (p[0]<<8) + p[1];
274                        pid = ((p[2]<<8) + p[3]) & PID_MASK;
275                        if (program_number == 0) {
276                                if (pat->networkPIDPresent) {
277                                        FORMATWARNING("PAT: More than one network_PID");
278                                }
279                                else {
280                                        pat->networkPIDPresent = TRUE;
281                                        pat->network_PID = pid;
282                                }
283                        }
284                        else {
285                                for (k = 0; k < index; ++k) {
286                                        if (pat->programs[k].program_number == program_number) {
287                                                FORMATWARNING("PAT: Duplicate program number");
288                                                goto nextSlot;
289                                        }
290                                }
291                                pat->programs[index].program_number = program_number;
292                                pat->programs[index].program_map_PID = pid;
293                                index++;
294                        }
295nextSlot: ;
296                }
297        }
298        pat->numPrograms = index;
299        *(((memId_t *)pat)-1) = memId;
300        *returnPat = pat;
301        memId = 0;      /* Don't delete below */
302
303ParseExit:
304        if (memId) {
305                /* delete the patSection memory */
306                memChainDestroy(memId);
307        }
308
309        return(err);
310}
311
312
313
314DHL_RESULT ParsePMT(const tDHL_PSI_DataArray *desc, MPEG_PMT **returnPmt)
315{
316        DHL_RESULT err = DHL_OK;
317        INT32 j, k;
318        INT32 numStreams;
319        INT32 len, len2;
320        MPEG_PMT *pmt;
321        INT32 program_info_length, es_info_length;
322        memChainSetup_t         memSetup = {MEM_LIMIT,NULL,NULL};
323        memId_t                 memId = NULL;
324        const UINT8 *p;
325        UINT8 *q;
326
327        if (!desc || desc->numSections < 1) {
328                return(DHL_FAIL_INVALID_PARAM);
329        }
330        if (desc->numSections > 1) {
331                DHL_OS_Printf("PMT: more than one PMT section sections > 0 ignored.\n");
332        }
333        /*
334         * First pass, we verify section syntax and count the number of streams
335         */
336        p = desc->sectPtr[0];
337        DHL_ASSERT(p != NULL, "ParsePMT: NULL section");
338
339        numStreams = 0;
340        if (p[SECTION_TID] != TS_PROGRAM_MAP_SECTION) {
341                /*
342                 * This thing isn't a PMT. Stop right here.
343                 */
344                FORMATWARNING("PMT: Bad table ID.");
345                err = DHL_FAIL_BAD_FORMAT;
346                goto ParseExit;
347        }
348        if ((p[SECTION_LEN_HI] & 0x80) != 0x80) {
349                FORMATWARNING("PAT: section_syntax_indicator not set");
350        }
351        if ((p[SECTION_LEN_HI] & 0x40) != 0x00) {
352                FORMATWARNING("PAT: private_indicator set");
353        }
354        len = (((p[SECTION_LEN_HI] & 0x0F) << 8) | p[SECTION_LEN_LO]) + 3;
355        if (p[SECTION_NUM] != 0) {
356                FORMATWARNING("PMT: section_number != 0");
357        }
358        if (p[SECTION_NUM_LAST] != 0) {
359                FORMATWARNING("PAT: last_section_number != 0");
360        }
361        program_info_length = ((p[10]<<8) + p[11]) & 0x0FFF;
362        if (program_info_length & 0x0C00) {
363                FORMATWARNING("PMT: first 2 bits of program_info_length not 00");
364        }
365        len2 = len - program_info_length - 16;
366        if (len2 < 0) {
367                FORMATWARNING("PMT: program descriptors extend beyond section");
368                err = DHL_FAIL_BAD_FORMAT;
369                goto ParseExit;         
370        }
371
372#if 0
373        // CRC üũ¸¦ Çϱ⠶§¹®¿¡ Á¦ÇÑÀ» µÎÁö ¸»ÀÚ.
374       
375        // cafrii 070423 add
376        //  À߸øµÈ sectionÀÌ ¿©±â·Î ³Ñ¾î¿Í¼­ Á×´Â ¹®Á¦ ¹ß»ý..
377        //
378        if (err || program_info_length > 100) {
379                OS_DbgPrintf("!! PMT seems invalid.. err %d, program_info_length %d\n",
380                                err, program_info_length);
381                err = DHL_FAIL_BAD_FORMAT;
382                goto ParseExit;
383        }
384#endif
385
386        p += program_info_length + 12;
387        while (len2 > 0) {
388                if (len2 < 5) {
389                        FORMATWARNING("PMT: junk bytes at end of table");
390                        break;
391                }
392                es_info_length = ((p[3]<<8) + p[4]) & 0x0FFF;
393                if (es_info_length & 0x0C00) {
394                        FORMATWARNING("PMT: first 2 bits of ES_info_length not 00");
395                }
396                if (len2 - es_info_length < 5) {
397                        FORMATWARNING("PMT: elementary stream descriptors extend beyond section");
398                        break;
399                }
400                /*
401                 * This is a hack to repair corrupted PMT's which we have received
402                 */
403                {
404                        //UINT32 hlen = es_info_length;
405                        INT32 hlen = (INT32)es_info_length; // cafrii 070423 add for safety
406                                // Ȥ½Ã ³»¿ëÀÌ ¾ûÅ͸®ÀÏ °æ¿ì hlen==0 Á¶°ÇÀ» °Ç³Ê¶Ù¾î ¹ö·Á À½¼ö°¡ µÉ ¼öµµ ÀÖ´Ù.
407                        UINT8 *hp = (UINT8 *)&p[5];
408                        UINT32 dtype, dlen;
409                        while(hlen > 0) {
410                                dtype = hp[0];
411                                dlen = hp[1];
412                                // descriptor 10 Â¥¸®°¡ Á¾Á¾ À߸øµÈ length¸¦ °®´Â °æ¿ì°¡ ÀÖ³ªº¸´Ù.
413                                if (dtype == 10 && dlen == 3) {
414                                        hp[1] = 4;
415                                        es_info_length++;
416                                        ((UINT8 *)p)[3] = es_info_length>>8;
417                                        ((UINT8 *)p)[4] = es_info_length&255;
418                                        break;
419                                }
420                                hp += (dlen+2);
421                                hlen -= (dlen+2);
422                        }
423                }
424                /*
425                 * End corrupted PMT hack
426                 */
427                len2 = len2 - es_info_length - 5;
428                p += es_info_length + 5;
429                numStreams++;
430        }
431        /*
432         * At this point, numStreams has the number of streams, which we can
433         * base the size of the PMT from.
434         */
435        /* create the memChain */
436        err = memChainCreate(&memId,&memSetup);
437        if (err) {
438                goto ParseExit;
439        }
440        /* allocate memory for pmtSection */
441        pmt = (MPEG_PMT *)((memId_t *)(memChainAlloc(memId,MPEG_PMTSize(numStreams)+sizeof(memId_t))) + 1);
442        checkMemoryError(pmt);
443
444        /*
445         * Second pass, we fill in the table.
446         * We assume that everything we verified or warned about above is still
447         * true. We already bailed out on fatal errors
448         */
449        p = desc->sectPtr[0];
450        pmt->PID = desc->pid;
451        pmt->program_number = ((p[SECTION_TID_EXT_HI] << 8) | 
452                                                        p[SECTION_TID_EXT_LO]);
453        pmt->version_number = (p[SECTION_VERSION] & SECTION_VERSION_MASK) >> 
454                                                         SECTION_VERSION_SHIFT;
455        pmt->current_next_indicator = (p[SECTION_VERSION] & SECTION_CNI_MASK) != 0;
456        pmt->PCR_PID = ((p[8] << 8) | p[9]) & PID_MASK;
457        pmt->numStreams = numStreams;
458
459        len2 = len - program_info_length - 16;
460
461        p += 12;
462        pmt->descriptor_length = program_info_length;
463        pmt->descriptors = (UINT8 *)memChainAlloc(memId,program_info_length*sizeof(UINT8));
464        checkMemoryError(pmt->descriptors);
465        for (j=0; j<program_info_length; j++) {
466                pmt->descriptors[j]             = *p++;
467        }
468
469        for (j = 0; j < numStreams; ++j) {
470                pmt->streams[j].stream_type = p[0];
471                pmt->streams[j].elementary_PID = ((p[1]<<8) | p[2]) & PID_MASK;
472                es_info_length = ((p[3]<<8) + p[4]) & 0x0FFF;
473                p += 5;
474                pmt->streams[j].descriptor_length = es_info_length;
475                pmt->streams[j].descriptors = (UINT8 *)memChainAlloc(memId,es_info_length*sizeof(UINT8));
476                checkMemoryError(pmt->streams[j].descriptors);
477                for (k=0; k<es_info_length; k++) {
478                        pmt->streams[j].descriptors[k]  = *p++;
479                }
480                if (GetMpegDescriptor(pmt->streams[j].descriptors,es_info_length,
481                        video_stream_tag,0/*instance*/,&q) == DHL_OK) {
482                        parse_video_stream_descriptor(q,memId,&pmt->streams[j].videoStreamDescriptor);
483                }
484#if 0 // cafrii, À̰ÍÀº ARIB specÀÓ. »èÁ¦..
485                if (GetMpegDescriptor(pmt->streams[j].descriptors,es_info_length,
486                        video_decode_control_tag,0/*instance*/,&q) == DHL_OK) {
487                        parse_video_stream_descriptor(q,memId,&pmt->streams[j].videoDecodeControlDescriptor);
488                }
489#endif
490        }
491        *(((memId_t *)pmt)-1) = memId;
492        *returnPmt = pmt;
493        memId = 0;                              /* Don't delete below */
494
495ParseExit:
496        if (memId) {
497                /* delete the patSection memory */
498                memChainDestroy(memId);
499        }
500       
501        return(err);
502}
503
504// FlattenPMT creates an MPEG program map section from a PMT structure
505DHL_RESULT FlattenPMT(const MPEG_PMT *pmt, UINT32 *pmtSectionLength, UINT8 **pmtSection)
506{
507        UINT16 i,j;
508        UINT8 *p;
509        UINT32 len = PMT_SECTION_HEADER_LENGTH;
510        UINT8 *buf;
511        UINT32 crc;
512
513        dprint(1, "FlattenPMT(0x%08X,0x%08X,0x%08X)\n", (UINT32)pmt, (UINT32)pmtSectionLength, (UINT32)pmtSection);
514
515        if (!pmt) {
516                dprint(0, "NULL Program Mapping Table\n");
517                dprint(1, "FlattenPMT -->(0x%08X,ret %d)\n",    (UINT32)*pmtSection, DHL_FAIL_NOT_FOUND);
518               
519                return DHL_FAIL_NOT_FOUND;
520        }
521
522        /* allocate return buffer */
523        buf = (UINT8 *)DHL_OS_Malloc(FLAT_PSI_MAX_SECTION_SIZE); 
524        if (!buf) 
525        {
526                dprint(1, "FlattenPMT -->(0x%08X,ret %d)\n", (UINT32)*pmtSection,DHL_FAIL_OUT_OF_MEMORY);
527                return DHL_FAIL_OUT_OF_MEMORY;
528        }
529
530        /* fill in PMT header info (except length) */
531        buf[SECTION_TID] = TS_PROGRAM_MAP_SECTION;
532
533        /* section length filled later, after it's known */
534
535        /* program_number */
536        buf[SECTION_TID_EXT_HI] = (pmt->program_number & 0xFF00) >> 8;
537        buf[SECTION_TID_EXT_LO] = pmt->program_number & 0xFF;
538
539        buf[SECTION_VERSION] = (0xC0 /* reserved */ | 
540                                                                   ((pmt->version_number << SECTION_VERSION_SHIFT) & SECTION_VERSION_MASK) |
541                                                                   (pmt->current_next_indicator & SECTION_CNI_MASK));
542
543        buf[SECTION_NUM] = 0;
544        buf[SECTION_NUM_LAST] = 0;
545
546        buf[PMT_PCR_PID_HI] = ( 0xE0 /* reserved */ | ((pmt->PCR_PID & PCR_PID_MASK_HI) >> 8));
547        buf[PMT_PCR_PID_LO] = ( pmt->PCR_PID & PCR_PID_MASK_LO );
548
549        buf[PMT_PRGM_INFO_LEN_HI] = ( 0xF0 /* reserved */ | ((pmt->descriptor_length & 0xF00) >> 8) );
550        buf[PMT_PRGM_INFO_LEN_LO] = ( pmt->descriptor_length & 0xFF );
551
552        /* program info descriptors */
553        len += pmt->descriptor_length;
554        if (len >= FLAT_PSI_MAX_SECTION_SIZE) {
555                dprint(0, "PMT: program descriptors extend beyond max section length");
556                goto FlattenExit;
557        }
558        p = &buf[PMT_PRGM_INFO_START];
559        for (i=0; i<pmt->descriptor_length; i++) {
560                *p++ = pmt->descriptors[i];
561        }
562
563        /* stream info loop */
564        for (i=0; i<pmt->numStreams; i++) {
565                /* stream type */
566                *p++ = pmt->streams[i].stream_type; 
567                len++;
568
569                /* elementary PID */
570                *p++ = ( 0xE0 /*reserved*/ | ((pmt->streams[i].elementary_PID & 0x1F00)>>8)); 
571                *p++ = ( pmt->streams[i].elementary_PID & 0xFF ); 
572                len += 2;
573
574                /* ES_info_length */
575                *p++ = ( 0xF0 /*reserved*/ | (( pmt->streams[i].descriptor_length & 0x0F00)>>8)); 
576                *p++ = ( pmt->streams[i].descriptor_length & 0xFF ); 
577                len += 2;
578
579                /* ES_info descriptors */
580                len += pmt->streams[i].descriptor_length;
581                if (len >= FLAT_PSI_MAX_SECTION_SIZE) {
582                        dprint(0, "PMT: ES_info descriptors extend beyond max section length");
583                        goto FlattenExit;
584                }
585                for (j=0; j<pmt->streams[i].descriptor_length; j++) {
586                        *p++ = pmt->streams[i].descriptors[j];
587                }
588        }
589
590        /* add CRC space to overall section length and verify it's OK */
591        len += 4;
592        if (len >= FLAT_PSI_MAX_SECTION_SIZE)
593        {
594                dprint(0, "PMT: CRC extends beyond max section length");
595                goto FlattenExit;
596        }
597
598        /* fill in section length field */
599        buf[SECTION_LEN_HI] = (0x80 /* section_syntax_indicator, 0 */ | 
600                                                   0x30 /* reserved */ |
601                                                   ((len-3) & 0xF00) >> 8);
602        buf[SECTION_LEN_LO] = ((len-3) & 0xFF);
603
604        /* calculate and add 4-byte CRC
605         * we don't include CRC portion in calculation, hence "len-4"
606         */
607        crc = DHL_UTL_CalcCRC32(DHL_CRC_START,buf, (len-4));
608        *p++ = (crc >> 24) & 0xFF;
609        *p++ = (crc >> 16) & 0xFF;
610        *p++ = (crc >> 8) & 0xFF;
611        *p++ = crc & 0xFF;
612
613        /* return flattend section and length of data */
614        *pmtSectionLength = len;
615        *pmtSection = buf;
616       
617        dprint(1, "FlattenPMT -->(0x%08X,ret %d)\n", (UINT32)*pmtSection, DHL_OK);
618       
619        return DHL_OK;
620
621FlattenExit:
622        if( buf )
623                DHL_OS_Free((void**)&buf);
624       
625        dprint(1, "FlattenPMT -->(0x%08X, ret %d)\n", (UINT32)*pmtSection, DHL_FAIL_BAD_FORMAT);
626       
627        return DHL_FAIL_BAD_FORMAT;
628}
629
630
631DHL_RESULT GetMpegDescriptor (UINT8 *descriptors, UINT16 len, UINT8 tag,
632                                                        UINT16 instance, UINT8 **descriptor)
633{
634        UINT8                   *p;
635        UINT16                  count;
636        UINT8                   descriptor_length;
637        DHL_RESULT              err;
638
639        /* search for descriptor of type 'tag' */
640        count = 0;
641        err = DHL_FAIL_NOT_FOUND;
642        p = descriptors;
643        while (p < descriptors + len) {
644                if (*p == tag) {
645                        if (count == instance) {
646                                /* check for length error */
647                                descriptor_length = p[1];
648                                if ((p + descriptor_length + 2) <= (descriptors + len)) {
649                                        if (descriptor) {
650                                                *descriptor = p;
651                                        }
652                                        err = DHL_OK;
653                                }
654                                else {
655                                        err = DHL_FAIL_BAD_FORMAT;
656                                }
657                                break;  /* break 'while' */
658                        }
659                        else {
660                                count++;
661                        }
662                }
663                p++;    /* skip tag */
664                descriptor_length = *p++;
665                p += descriptor_length;
666        }
667
668        return (err);
669}
670
671void FreeMpegDescriptor (void *descriptorPtr)
672{
673        memChainDestroy(*(((memId_t *)descriptorPtr)-1));
674}
675
676#if COMMENT
677____Free____(){}
678#endif
679
680
681void FreePAT(MPEG_PAT *pat)
682{
683        memChainDestroy(*(((memId_t *)pat)-1));
684}
685
686void FreePMT(MPEG_PMT *pmt)
687{
688        memChainDestroy(*(((memId_t *)pmt)-1));
689}
690
691
692
693#if COMMENT
694____Debug____(){}
695#endif
696
697
698
699
700#if COMMENT
701____Symbol____(){}
702#endif
703
704
705
706
707#if COMMENT
708____Init____(){}
709#endif
710
711
712
713/* end of file */
714
Note: See TracBrowser for help on using the repository browser.