source: svn/newcon3bcm2_21bu/BSEAV/lib/utils/bdemux_pes.c @ 46

Last change on this file since 46 was 46, checked in by megakiss, 11 years ago

459Mhz로 OTC 주파수 변경

  • Property svn:executable set to *
File size: 5.4 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2006-2007, 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: bdemux_pes.c $
11 * $brcm_Revision: 2 $
12 * $brcm_Date: 2/16/07 10:16a $
13 *
14 * Module Description:
15 *
16 * MPEG-2 Demux library
17 *
18 * Revision History:
19 *
20 * $brcm_Log: /BSEAV/lib/utils/bdemux_pes.c $
21 *
22 * 2   2/16/07 10:16a vsilyaev
23 * PR 27443: Added audio decoder status from various pipeline stages, TS,
24 * PES, AC3 and PCM counters
25 *
26 * 1   10/16/06 11:35a vsilyaev
27 * PR 24956 PR 24844: Software MPEG-2 TS and PES demultiplexor
28 *
29 *
30 *******************************************************************************/
31#include "bstd.h"
32#include "bdemux_pes.h"
33#include "biobits.h"
34#include "bkni.h"
35
36BDBG_MODULE(bdemux_pes);
37
38BDBG_OBJECT_ID(bdemux_pes);
39
40typedef enum {bdemux_pes_result_match, bdemux_pes_result_nomatch, bdemux_pes_result_more} bdemux_pes_result;
41void 
42bdemux_pes_init(bdemux_pes *pes, uint8_t id)
43{
44        BDBG_OBJECT_INIT(pes, bdemux_pes);
45        pes->state = bdemux_pes_state_sync;
46        pes->pkt_len = 0;
47        pes->pkt_offset = 0;
48        pes->id = id;
49        pes->ts_flags = 0;
50        pes->hold_enable = false;
51        pes->pes_packets = 0;
52        return;
53}
54
55static bdemux_pes_result
56b_demux_parse_pes_hdr(bdemux_pes *pes, const uint8_t *pes_header, size_t len)
57{
58        uint32_t pts=0;
59        unsigned flags = 0;
60
61        if( (pes_header[0]|pes_header[1])!=0x00 || pes_header[2]!=0x01 ) { /*  packet_start_code_prefix */
62                BDBG_WRN(("bdemux_ts_data: %#lx invalid packet_start_code_prefix 0x%02x%02x%02x != 0x000001", (unsigned long)pes, pes_header[0], pes_header[1], pes_header[2]));
63                return bdemux_pes_result_nomatch;
64        }
65        if(pes->id && pes->id!=pes_header[3]) {
66                BDBG_WRN(("bdemux_ts_data: %#lx unknown pes id %#x(%#x)", (unsigned long)pes, pes_header[3], pes->id));
67                return bdemux_pes_result_nomatch;
68        }
69        pes->pkt_len = B_TS_LOAD16(pes_header,4);
70
71        if(B_GET_BIT(pes_header[6], 2)) {
72                flags = BDEMUX_PES_DATA_ALIGMENT;
73        }
74        if (B_GET_BITS(pes_header[7], 7, 6) & 2) {
75                if (len<14) {
76                        return bdemux_pes_result_more;
77                }
78                pts = 
79                 /* pts_32_30 */((uint32_t)B_GET_BITS(pes_header[9], 3, 1)<<29) |
80                 /* pts_29_22 */((uint32_t)pes_header[10]<<21) |
81                 /* pts_21_15 */((uint32_t)B_GET_BITS(pes_header[11], 7, 1)<<14) |
82                 /* pts_14_7 */((uint32_t)pes_header[12]<<6) |
83                 /* pts_6_0 */B_GET_BITS(pes_header[13], 7, 2);
84                flags |= BDEMUX_PES_PTS;
85        }
86        pes->pes_packets++;
87        bdemux_pes_header(pes, flags, pts);
88        pes->pkt_data_offset = 9+pes_header[8]; /* PES_header_data_length */
89        return bdemux_pes_result_match;
90}
91
92
93#define B_STR_FLAG(v,name) ((v)?#name " ":"")
94bdemux_ts_action
95bdemux_ts_data(bdemux_ts *ts, unsigned flags, const uint8_t *data, size_t len)
96{
97        bdemux_pes *pes = (bdemux_pes*)ts;
98
99        BDBG_OBJECT_ASSERT(pes, bdemux_pes);
100        BDBG_ASSERT(data);
101        BDBG_ASSERT(len>0);
102        BDBG_MSG(("bdemux_ts_data: %#lx %#lx:%u:%#x %s%s%s%s",(unsigned long)ts, (unsigned long)data, len, flags, B_STR_FLAG(flags&BDEMUX_TS_ERROR, ERR), B_STR_FLAG(flags&BDEMUX_TS_DISCONTINUITY, DISC),B_STR_FLAG(flags&BDEMUX_TS_MARKED_DISCONTINUITY, MDISC), B_STR_FLAG(flags&BDEMUX_TS_PAYLOAD_UNIT_START,START)));
103
104        if (pes->hold_enable) {
105                return bdemux_ts_action_hold;
106        }
107
108        /* ISO/IEC 13818-1 */
109        /* Table 2-18 -- PES packet */
110        pes->ts_flags |= flags;
111        if(flags&BDEMUX_TS_PAYLOAD_UNIT_START) {
112                switch(b_demux_parse_pes_hdr(pes, data, len)) {
113                case bdemux_pes_result_nomatch:
114                        pes->state = bdemux_pes_state_sync;
115                        return bdemux_ts_action_consume;
116                case bdemux_pes_result_more:
117                        BDBG_WRN(("bdemux_ts_data:%#lx partial pes header %u", (unsigned long)pes, len));
118                        BDBG_ASSERT(len<sizeof(pes->pes_header));
119                        BKNI_Memcpy(pes->pes_header, data, len);
120                        pes->pkt_offset = len;
121                        pes->state = bdemux_pes_state_hdr;
122                        return bdemux_ts_action_consume;
123                case bdemux_pes_result_match:
124                        break;
125                }
126                pes->state = bdemux_pes_state_data;
127                if(len>pes->pkt_data_offset) {
128                        pes->pkt_offset = pes->pkt_data_offset;
129                        len-=pes->pkt_data_offset;
130                        data+=pes->pkt_data_offset;
131                } else {
132                        pes->pkt_offset = len;
133                        len = 0;
134                }
135        }
136        if(pes->state == bdemux_pes_state_hdr) {
137                size_t to_copy;
138                BDBG_ASSERT(pes->pkt_offset<sizeof(pes->pes_header));
139                to_copy = sizeof(pes->pes_header) - pes->pkt_offset;
140                if (to_copy>len) { to_copy=len;}
141                BDBG_ASSERT(pes->pkt_offset+to_copy<=sizeof(pes->pes_header));
142                BKNI_Memcpy(pes->pes_header+pes->pkt_offset, data, len);
143                switch(b_demux_parse_pes_hdr(pes, data, len)) {
144                case bdemux_pes_result_nomatch:
145                        pes->state = bdemux_pes_state_sync;
146                        return bdemux_ts_action_consume;
147                case bdemux_pes_result_more:
148                        BDBG_ASSERT(to_copy==len);
149                        /* we have already copied out data */
150                        return bdemux_ts_action_consume;
151                case bdemux_pes_result_match:
152                        break;
153                }
154                pes->state = bdemux_pes_state_data;
155                if(pes->pkt_offset+len>pes->pkt_data_offset) {
156                        len-=pes->pkt_data_offset - pes->pkt_offset;
157                        data+=pes->pkt_data_offset - pes->pkt_offset;
158                        pes->pkt_offset = pes->pkt_data_offset;
159                } else {
160                        pes->pkt_offset += len;
161                        len = 0;
162                }
163        }
164        if(pes->state == bdemux_pes_state_data) {
165                bdemux_pes_data(pes, data, len, pes->ts_flags);
166                pes->ts_flags = 0; /* clear out flags */
167                pes->pkt_offset += len;
168        }
169        return bdemux_ts_action_consume;
170}
171
172
Note: See TracBrowser for help on using the repository browser.