MacGUI: Fix a warning on 10.5
[HandBrake.git] / libhb / demuxmpeg.c
blob93b3709c35869b4a4d32e96f3eb37396041443f5
1 /* $Id: demuxmpeg.c,v 1.4 2004/10/19 23:11:36 titer Exp $
3 This file is part of the HandBrake source code.
4 Homepage: <http://handbrake.m0k.org/>.
5 It may be used under the terms of the GNU General Public License. */
7 #include "hb.h"
9 /* Basic MPEG demuxer, only works with DVDs (2048 bytes packets) */
11 int hb_demux_ps( hb_buffer_t * buf_ps, hb_list_t * list_es )
13 hb_buffer_t * buf_es;
14 int pos;
16 pos = 0;
18 #define d (buf_ps->data)
20 /* pack_header */
21 if( d[pos] != 0 || d[pos+1] != 0 ||
22 d[pos+2] != 0x1 || d[pos+3] != 0xBA )
24 hb_log( "hb_demux_ps: not a PS packet (%02x%02x%02x%02x)",
25 d[pos], d[pos+1], d[pos+2], d[pos+3] );
26 return 0;
28 pos += 4; /* pack_start_code */
29 pos += 9; /* pack_header */
30 pos += 1 + ( d[pos] & 0x7 ); /* stuffing bytes */
32 /* system_header */
33 if( d[pos] == 0 && d[pos+1] == 0 &&
34 d[pos+2] == 0x1 && d[pos+3] == 0xBB )
36 int header_length;
38 pos += 4; /* system_header_start_code */
39 header_length = ( d[pos] << 8 ) + d[pos+1];
40 pos += 2 + header_length;
43 /* pes */
44 while( pos + 6 < buf_ps->size &&
45 d[pos] == 0 && d[pos+1] == 0 && d[pos+2] == 0x1 )
47 int id;
48 int pes_packet_length;
49 int pes_packet_end;
50 int pes_header_d_length;
51 int pes_header_end;
52 int has_pts;
53 int64_t pts = -1;
55 pos += 3; /* packet_start_code_prefix */
56 id = d[pos];
57 pos += 1;
59 pes_packet_length = ( d[pos] << 8 ) + d[pos+1];
60 pos += 2; /* pes_packet_length */
61 pes_packet_end = pos + pes_packet_length;
63 if( id != 0xE0 && id != 0xBD &&
64 ( id & 0xC0 ) != 0xC0 )
66 /* Not interesting */
67 pos = pes_packet_end;
68 continue;
71 has_pts = ( ( d[pos+1] >> 6 ) & 0x2 ) ? 1 : 0;
72 pos += 2; /* Required headers */
74 pes_header_d_length = d[pos];
75 pos += 1;
76 pes_header_end = pos + pes_header_d_length;
78 if( has_pts )
80 pts = ( ( ( (uint64_t) d[pos] >> 1 ) & 0x7 ) << 30 ) +
81 ( d[pos+1] << 22 ) +
82 ( ( d[pos+2] >> 1 ) << 15 ) +
83 ( d[pos+3] << 7 ) +
84 ( d[pos+4] >> 1 );
87 pos = pes_header_end;
89 if( id == 0xBD )
91 id |= ( d[pos] << 8 );
92 if( ( id & 0xF0FF ) == 0x80BD ) /* A52 */
94 pos += 4;
96 else if( ( id & 0xE0FF ) == 0x20BD || /* SPU */
97 ( id & 0xF0FF ) == 0xA0BD ) /* LPCM */
99 pos += 1;
103 /* Sanity check */
104 if( pos >= pes_packet_end )
106 pos = pes_packet_end;
107 continue;
110 /* Here we hit we ES payload */
111 buf_es = hb_buffer_init( pes_packet_end - pos );
113 buf_es->id = id;
114 buf_es->start = pts;
115 if (id == 0xE0) {
116 // Consume a chapter break, and apply it to the ES.
117 buf_es->new_chap = buf_ps->new_chap;
118 buf_ps->new_chap = 0;
120 memcpy( buf_es->data, d + pos, pes_packet_end - pos );
122 hb_list_add( list_es, buf_es );
124 pos = pes_packet_end;
127 #undef d
129 return 1;