OSDN Git Service

MacGui: Remove Target Size as a rate control option as it doesn't really work correct...
[handbrake-jp/handbrake-jp-git.git] / libhb / demuxmpeg.c
1 /* $Id: demuxmpeg.c,v 1.4 2004/10/19 23:11:36 titer Exp $
2
3    This file is part of the HandBrake source code.
4    Homepage: <http://handbrake.fr/>.
5    It may be used under the terms of the GNU General Public License. */
6
7 #include "hb.h"
8
9 static inline void check_mpeg_scr( hb_psdemux_t *state, int64_t scr, int tol )
10 {
11     /*
12      * This section of code implements the timing model of
13      * the "Standard Target Decoder" (STD) of the MPEG2 standard
14      * (specified in ISO 13818-1 sections 2.4.2, 2.5.2 & Annex D).
15      * The STD removes and corrects for clock discontinuities so
16      * that the time stamps on the video, audio & other media
17      * streams can be used for cross-media synchronization. To do
18      * this the STD has its own timestamp value, the System Clock
19      * Reference or SCR, in the PACK header. Clock discontinuities
20      * are detected using the SCR & and the adjustment needed
21      * to correct post-discontinuity timestamps to be contiguous
22      * with pre-discontinuity timestamps is computed from pre- and
23      * post-discontinuity values of the SCR. Then this adjustment
24      * is applied to every media timestamp (PTS).
25      *
26      * ISO 13818-1 says there must be an SCR at least every 700ms
27      * (100ms for Transport Streams) so if the difference between
28      * this SCR & the previous is >700ms it's a discontinuity.
29      * If the difference is negative it's non-physical (time doesn't
30      * go backward) and must also be a discontinuity. When we find a
31      * discontinuity we adjust the scr_offset so that the SCR of the
32      * new packet lines up with that of the previous packet.
33      */
34
35     // we declare a discontinuity if there's a gap of more than
36     // 'tol'ms between the last scr & this or if this scr goes back
37     // by more than half a frame time.
38     int64_t scr_delta = scr - state->last_scr;
39     if ( scr_delta > 90*tol || scr_delta < -90*10 )
40     {
41         ++state->scr_changes;
42         state->last_pts = -1;
43     }
44     state->last_scr = scr;
45 }
46
47 /* Basic MPEG demuxer */
48
49 int hb_demux_ps( hb_buffer_t * buf_ps, hb_list_t * list_es, hb_psdemux_t* state )
50 {
51     hb_buffer_t * buf_es;
52     int           pos = 0;
53
54 #define d (buf_ps->data)
55
56     /* pack_header */
57     if( d[pos] != 0 || d[pos+1] != 0 ||
58         d[pos+2] != 0x1 || d[pos+3] != 0xBA )
59     {
60         hb_log( "hb_demux_ps: not a PS packet (%02x%02x%02x%02x)",
61                 d[pos], d[pos+1], d[pos+2], d[pos+3] );
62         return 0;
63     }
64     pos += 4;                    /* pack_start_code */
65
66     if ( state )
67     {
68         /* extract the system clock reference (scr) */
69         int64_t scr = ((uint64_t)(d[pos] & 0x38) << 27) |
70                       ((uint64_t)(d[pos] & 0x03) << 28) |
71                       ((uint64_t)(d[pos+1]) << 20) |
72                       ((uint64_t)(d[pos+2] >> 3) << 15) |
73                       ((uint64_t)(d[pos+2] & 3) << 13) |
74                       ((uint64_t)(d[pos+3]) << 5) |
75                       (d[pos+4] >> 3);
76         check_mpeg_scr( state, scr, 300 );
77     }
78
79     pos += 9;                    /* pack_header */
80     pos += 1 + ( d[pos] & 0x7 ); /* stuffing bytes */
81
82     /* system_header */
83     if( d[pos] == 0 && d[pos+1] == 0 &&
84         d[pos+2] == 0x1 && d[pos+3] == 0xBB )
85     {
86         int header_length;
87
88         pos           += 4; /* system_header_start_code */
89         header_length  = ( d[pos] << 8 ) + d[pos+1];
90         pos           += 2 + header_length;
91     }
92
93     /* pes */
94     while( pos + 6 < buf_ps->size &&
95            d[pos] == 0 && d[pos+1] == 0 && d[pos+2] == 0x1 )
96     {
97         int      id;
98         int      pes_packet_length;
99         int      pes_packet_end;
100         int      pes_header_d_length;
101         int      pes_header_end;
102         int      has_pts;
103         int64_t  pts = -1, dts = -1;
104
105         pos               += 3;               /* packet_start_code_prefix */
106         id           = d[pos];
107         pos               += 1;
108
109         /* pack_header */
110         if( id == 0xBA)
111         {
112             pos += 10 + (d[pos+9] & 7);
113             continue;
114         }
115
116         /* system_header */
117         if( id == 0xBB )
118         {
119             int header_length;
120
121             header_length  = ( d[pos] << 8 ) + d[pos+1];
122             pos           += 2 + header_length;
123             continue;
124         }
125
126         pes_packet_length  = ( d[pos] << 8 ) + d[pos+1];
127         pos               += 2;               /* pes_packet_length */
128         pes_packet_end     = pos + pes_packet_length;
129
130         if( id != 0xE0 && id != 0xBD &&
131             ( id & 0xC0 ) != 0xC0  )
132         {
133             /* Not interesting */
134             pos = pes_packet_end;
135             continue;
136         }
137
138         has_pts            = d[pos+1] >> 6;
139         pos               += 2;               /* Required headers */
140
141         pes_header_d_length  = d[pos];
142         pos                    += 1;
143         pes_header_end          = pos + pes_header_d_length;
144
145         if( has_pts )
146         {
147             pts = ( (uint64_t)(d[pos] & 0xe ) << 29 ) +
148                   ( d[pos+1] << 22 ) +
149                   ( ( d[pos+2] >> 1 ) << 15 ) +
150                   ( d[pos+3] << 7 ) +
151                   ( d[pos+4] >> 1 );
152             if ( has_pts & 1 )
153             {
154                 dts = ( (uint64_t)(d[pos+5] & 0xe ) << 29 ) +
155                       ( d[pos+6] << 22 ) +
156                       ( ( d[pos+7] >> 1 ) << 15 ) +
157                       ( d[pos+8] << 7 ) +
158                       ( d[pos+9] >> 1 );
159             }
160             else
161             {
162                 dts = pts;
163             }
164         }
165
166         pos = pes_header_end;
167
168         if( id == 0xBD )
169         {
170             id |= ( d[pos] << 8 );
171             if( ( id & 0xF0FF ) == 0x80BD ) /* A52 */
172             {
173                 pos += 4;
174             }
175             else if( ( id & 0xE0FF ) == 0x20BD || /* SPU */
176                      ( id & 0xF0FF ) == 0xA0BD )  /* LPCM */
177             {
178                 pos += 1;
179             }
180         }
181
182         /* Sanity check */
183         if( pos >= pes_packet_end )
184         {
185             pos = pes_packet_end;
186             continue;
187         }
188
189         /* Here we hit we ES payload */
190         buf_es = hb_buffer_init( pes_packet_end - pos );
191
192         buf_es->id       = id;
193         buf_es->start    = pts;
194         buf_es->renderOffset = dts;
195         buf_es->stop     = -1;
196         if (id == 0xE0) {
197             // Consume a chapter break, and apply it to the ES.
198             buf_es->new_chap = buf_ps->new_chap;
199             buf_ps->new_chap = 0;
200         }
201         memcpy( buf_es->data, d + pos, pes_packet_end - pos );
202
203         hb_list_add( list_es, buf_es );
204
205         pos = pes_packet_end;
206     }
207
208 #undef d
209
210     return 1;
211 }
212
213 // mpeg transport stream demuxer. the elementary stream headers have been
214 // stripped off and buf_ps has all the info gleaned from them: id is set,
215 // start contains the pts (if any), renderOffset contains the dts (if any)
216 // and stop contains the pcr (if it changed).
217 int hb_demux_ts( hb_buffer_t *buf_ps, hb_list_t *list_es, hb_psdemux_t *state )
218 {
219     if ( state )
220     {
221         // we're keeping track of timing (i.e., not in scan)
222         // check if there's a new pcr in this packet
223         if ( buf_ps->stop >= 0 )
224         {
225             // we have a new pcr
226             check_mpeg_scr( state, buf_ps->stop, 300 );
227             buf_ps->stop = -1;
228         }
229         if ( buf_ps->start >= 0 )
230         {
231             // Program streams have an SCR in every PACK header so they
232             // can't lose their clock reference. But the PCR in Transport
233             // streams is typically on <.1% of the packets. If a PCR
234             // packet gets lost and it marks a clock discontinuity then
235             // the data following it will be referenced to the wrong
236             // clock & introduce huge gaps or throw our A/V sync off.
237             // We try to protect against that here by sanity checking
238             // timestamps against the current reference clock and discarding
239             // packets where the DTS is "too far" from its clock.
240             int64_t fdelta = buf_ps->start - state->last_scr;
241             if ( fdelta < -300 * 90000LL || fdelta > 300 * 90000LL )
242             {
243                 // packet too far behind or ahead of its clock reference
244                 ++state->dts_drops;
245                 return 1;
246             }
247             if ( state->last_pts >= 0 )
248             {
249                 fdelta = buf_ps->start - state->last_pts;
250                 if ( fdelta < -5 * 90000LL || fdelta > 5 * 90000LL )
251                 {
252                     // Packet too far from last. This may be a NZ TV broadcast
253                     // as they like to change the PCR without sending a PCR
254                     // update. Since it may be a while until they actually tell
255                     // us the new PCR use the PTS as the PCR.
256                     ++state->scr_changes;
257                     state->last_scr = buf_ps->start;
258                 }
259             }
260             state->last_pts = buf_ps->start;
261         }
262     }
263
264     hb_buffer_t *buf = hb_buffer_init( buf_ps->alloc );
265     hb_buffer_swap_copy( buf_ps, buf );
266     if (buf->type == VIDEO_BUF) {
267         // Consume a chapter break
268         buf_ps->new_chap = 0;
269     }
270     hb_list_add( list_es, buf );
271
272     return 1;
273 }
274
275 // "null" demuxer (makes a copy of input buf & returns it in list)
276 // used when the reader for some format includes its own demuxer.
277 // for example, ffmpeg.
278 int hb_demux_null( hb_buffer_t * buf_ps, hb_list_t * list_es, hb_psdemux_t* state )
279 {
280     // if we don't have a time offset yet, use this timestamp as the offset.
281     if ( state && state->scr_changes == 0 &&
282          ( buf_ps->start >= 0 || buf_ps->renderOffset >= 0 ) )
283     {
284         ++state->scr_changes;
285         state->last_scr = buf_ps->start >= 0 ? buf_ps->start : buf_ps->renderOffset;
286     }
287
288     hb_buffer_t *buf = hb_buffer_init( buf_ps->alloc );
289     hb_buffer_swap_copy( buf_ps, buf );
290     hb_list_add( list_es, buf );
291
292     return 1;
293 }
294
295 const hb_muxer_t hb_demux[] = { hb_demux_ps, hb_demux_ts, hb_demux_null };