source: svn/trunk/newcon3bcm2_21bu/BSEAV/lib/mpeg2_ts_parse/ts_pmt.c

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

1.phkim

  1. revision copy newcon3sk r27
  • Property svn:executable set to *
File size: 4.3 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2003, 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: ts_pmt.c $
11 * $brcm_Revision: 1 $
12 * $brcm_Date: 2/7/05 11:30p $
13 *
14 * [File Description:]
15 *
16 * Revision History:
17 *
18 * $brcm_Log: /BSEAV/lib/mpeg2_ts_parse/ts_pmt.c $
19 *
20 * 1   2/7/05 11:30p dlwin
21 * Merge down for release 2005_REFSW_MERGETOMAIN:
22 *
23 * Irvine_BSEAVSW_Devel/5   7/6/04 3:54p erickson
24 * PR11771: settop api dataflow redesign
25 *
26 * Irvine_BSEAVSW_Devel/4   5/4/04 1:52p erickson
27 * PR10938: added bounds checking and PMT and PAT validation in order to
28 * prevent segfaults on bad data
29 *
30 * Irvine_BSEAVSW_Devel/3   2/4/04 9:56a erickson
31 * PR9217: converted BDBG_ASSERT calls to CHECK calls. Don't assert on bad
32 * data.
33 *
34 * Irvine_BSEAVSW_Devel/2   9/8/03 10:04a marcusk
35 * Added routines to get the number of things.
36 *
37 * Irvine_BSEAVSW_Devel/1   8/29/03 5:05p marcusk
38 * Initial Version.
39 *
40 ***************************************************************************/
41#include "bstd.h"
42#include "ts_priv.h"
43#include "ts_pmt.h"
44BDBG_MODULE(ts_pmt);
45
46#define PROGRAM_INFO_LENGTH_OFFSET (TS_PSI_LAST_SECTION_NUMBER_OFFSET+3)
47#define PROGRAM_INFO_LENGTH(buf) (TS_READ_16(&buf[PROGRAM_INFO_LENGTH_OFFSET])&0xFFF)
48#define DESCRIPTOR_BASE(buf) (&buf[TS_PSI_LAST_SECTION_NUMBER_OFFSET+5])
49#define STREAM_BASE(buf) (TS_PSI_LAST_SECTION_NUMBER_OFFSET + 5 + PROGRAM_INFO_LENGTH(buf))
50
51bool TS_PMT_validate(const uint8_t *buf, unsigned bfrSize)
52{
53        int sectionEnd = TS_PSI_GET_SECTION_LENGTH(buf) + TS_PSI_SECTION_LENGTH_OFFSET;
54        int programInfoEnd = PROGRAM_INFO_LENGTH(buf) + PROGRAM_INFO_LENGTH_OFFSET;
55
56        return (buf[0] == 0x2) &&
57                sectionEnd < (int)bfrSize &&
58                programInfoEnd < (int)bfrSize &&
59                programInfoEnd < sectionEnd;
60}
61
62static int TS_PMT_P_getStreamByteOffset( const uint8_t *buf, unsigned bfrSize, int streamNum )
63{
64        int byteOffset;
65        int i;
66
67        /* After the last descriptor */
68        byteOffset = STREAM_BASE(buf);
69
70        for (i=0; i < streamNum; i++)
71        {
72                if (byteOffset >= (int)bfrSize || byteOffset >= TS_PSI_MAX_BYTE_OFFSET(buf))
73                        return -1;
74                byteOffset += 5 + (TS_READ_16( &buf[byteOffset+3] ) & 0xFFF);
75        }
76
77        return byteOffset;
78}
79
80
81uint16_t TS_PMT_getPcrPid( const uint8_t *buf, unsigned bfrSize)
82{
83        BSTD_UNUSED(bfrSize);
84        return (uint16_t)(TS_READ_16( &buf[TS_PSI_LAST_SECTION_NUMBER_OFFSET+1] ) & 0x1FFF);
85}
86
87TS_PSI_descriptor TS_PMT_getDescriptor( const uint8_t *buf, unsigned bfrSize, int descriptorNum )
88{
89        const uint8_t *descriptorBase = DESCRIPTOR_BASE(buf);
90        uint32_t descriptorsLength = PROGRAM_INFO_LENGTH(buf);
91
92        /* Any time we dereference memory based on the contents of live data,
93        we should check. */
94        if (descriptorBase - buf >= (int)bfrSize) {
95                return NULL;
96        }
97        bfrSize -= (descriptorBase - buf);
98        if (bfrSize < descriptorsLength) {
99                BDBG_WRN(("Invalid descriptor length: %d>=%d", descriptorsLength, bfrSize));
100                return NULL;
101        }
102        return TS_P_getDescriptor(descriptorBase, descriptorsLength, descriptorNum);
103}
104
105int TS_PMT_getNumStreams( const uint8_t *buf, unsigned bfrSize)
106{
107        int byteOffset;
108        int i = 0;
109
110        byteOffset = STREAM_BASE(buf);
111
112        while (byteOffset < TS_PSI_MAX_BYTE_OFFSET(buf) && byteOffset < (int)bfrSize)
113        {
114                byteOffset += 5 + (TS_READ_16( &buf[byteOffset+3] ) & 0xFFF);
115                i++;
116        }
117
118        return i;
119}
120
121BERR_Code TS_PMT_getStream( const uint8_t *buf, unsigned bfrSize, int streamNum, TS_PMT_stream *p_stream )
122{
123        int byteOffset;
124
125        byteOffset = TS_PMT_P_getStreamByteOffset( buf, bfrSize, streamNum );
126        if (byteOffset == -1)
127                return BERR_INVALID_PARAMETER;
128
129        p_stream->stream_type = buf[byteOffset];
130        p_stream->elementary_PID = (uint16_t)(TS_READ_16( &buf[byteOffset+1] ) & 0x1FFF);
131
132        return BERR_SUCCESS;
133}
134
135TS_PSI_descriptor TS_PMT_getStreamDescriptor( const uint8_t *buf, unsigned bfrSize, int streamNum, int descriptorNum )
136{
137        int byteOffset;
138
139        byteOffset = TS_PMT_P_getStreamByteOffset( buf, bfrSize, streamNum );
140        if (byteOffset == -1)
141                return NULL;
142
143        return (TS_P_getDescriptor(&buf[byteOffset+5], TS_READ_16(&buf[byteOffset+3])&0xFFF, descriptorNum ));
144}
Note: See TracBrowser for help on using the repository browser.