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. */
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
)
18 #define d (buf_ps->data)
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] );
28 pos
+= 4; /* pack_start_code */
29 pos
+= 9; /* pack_header */
30 pos
+= 1 + ( d
[pos
] & 0x7 ); /* stuffing bytes */
33 if( d
[pos
] == 0 && d
[pos
+1] == 0 &&
34 d
[pos
+2] == 0x1 && d
[pos
+3] == 0xBB )
38 pos
+= 4; /* system_header_start_code */
39 header_length
= ( d
[pos
] << 8 ) + d
[pos
+1];
40 pos
+= 2 + header_length
;
44 while( pos
+ 6 < buf_ps
->size
&&
45 d
[pos
] == 0 && d
[pos
+1] == 0 && d
[pos
+2] == 0x1 )
48 int pes_packet_length
;
50 int pes_header_d_length
;
55 pos
+= 3; /* packet_start_code_prefix */
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 )
71 has_pts
= ( ( d
[pos
+1] >> 6 ) & 0x2 ) ? 1 : 0;
72 pos
+= 2; /* Required headers */
74 pes_header_d_length
= d
[pos
];
76 pes_header_end
= pos
+ pes_header_d_length
;
80 pts
= ( ( ( (uint64_t) d
[pos
] >> 1 ) & 0x7 ) << 30 ) +
82 ( ( d
[pos
+2] >> 1 ) << 15 ) +
91 id
|= ( d
[pos
] << 8 );
92 if( ( id
& 0xF0FF ) == 0x80BD ) /* A52 */
96 else if( ( id
& 0xE0FF ) == 0x20BD || /* SPU */
97 ( id
& 0xF0FF ) == 0xA0BD ) /* LPCM */
104 if( pos
>= pes_packet_end
)
106 pos
= pes_packet_end
;
110 /* Here we hit we ES payload */
111 buf_es
= hb_buffer_init( pes_packet_end
- pos
);
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
;