Mercurial > libavformat.hg
annotate mpeg.c @ 357:f4f573c7dc56 libavformat
Patch for MPEG-2 VOB headers by (Jimmy Blair <blueskyjb at verizon dot net>)
author | michael |
---|---|
date | Sun, 01 Feb 2004 13:06:46 +0000 |
parents | 72c7cf2f3a7a |
children | cbcbaeff1f2c |
rev | line source |
---|---|
0 | 1 /* |
2 * MPEG1/2 mux/demux | |
3 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard. | |
4 * | |
5 * This library is free software; you can redistribute it and/or | |
6 * modify it under the terms of the GNU Lesser General Public | |
7 * License as published by the Free Software Foundation; either | |
8 * version 2 of the License, or (at your option) any later version. | |
9 * | |
10 * This library is distributed in the hope that it will be useful, | |
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 * Lesser General Public License for more details. | |
14 * | |
15 * You should have received a copy of the GNU Lesser General Public | |
16 * License along with this library; if not, write to the Free Software | |
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 */ | |
19 #include "avformat.h" | |
20 | |
21 #define MAX_PAYLOAD_SIZE 4096 | |
310 | 22 //#define DEBUG_SEEK |
0 | 23 |
346
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
24 #undef NDEBUG |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
25 #include <assert.h> |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
26 |
0 | 27 typedef struct { |
65 | 28 uint8_t buffer[MAX_PAYLOAD_SIZE]; |
0 | 29 int buffer_ptr; |
335
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
30 int nb_frames; /* number of starting frame encountered (AC3) */ |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
31 int frame_start_offset; /* starting offset of the frame + 1 (0 if none) */ |
65 | 32 uint8_t id; |
0 | 33 int max_buffer_size; /* in bytes */ |
34 int packet_number; | |
65 | 35 int64_t start_pts; |
331
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
36 int64_t start_dts; |
336 | 37 uint8_t lpcm_header[3]; |
38 int lpcm_align; | |
0 | 39 } StreamInfo; |
40 | |
41 typedef struct { | |
42 int packet_size; /* required packet size */ | |
43 int packet_number; | |
44 int pack_header_freq; /* frequency (in packets^-1) at which we send pack headers */ | |
45 int system_header_freq; | |
335
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
46 int system_header_size; |
0 | 47 int mux_rate; /* bitrate in units of 50 bytes/s */ |
48 /* stream info */ | |
49 int audio_bound; | |
50 int video_bound; | |
51 int is_mpeg2; | |
52 int is_vcd; | |
331
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
53 int scr_stream_index; /* stream from which the system clock is |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
54 computed (VBR case) */ |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
55 int64_t last_scr; /* current system clock */ |
0 | 56 } MpegMuxContext; |
57 | |
58 #define PACK_START_CODE ((unsigned int)0x000001ba) | |
59 #define SYSTEM_HEADER_START_CODE ((unsigned int)0x000001bb) | |
60 #define SEQUENCE_END_CODE ((unsigned int)0x000001b7) | |
61 #define PACKET_START_CODE_MASK ((unsigned int)0xffffff00) | |
62 #define PACKET_START_CODE_PREFIX ((unsigned int)0x00000100) | |
63 #define ISO_11172_END_CODE ((unsigned int)0x000001b9) | |
64 | |
65 /* mpeg2 */ | |
66 #define PROGRAM_STREAM_MAP 0x1bc | |
67 #define PRIVATE_STREAM_1 0x1bd | |
68 #define PADDING_STREAM 0x1be | |
69 #define PRIVATE_STREAM_2 0x1bf | |
70 | |
71 | |
72 #define AUDIO_ID 0xc0 | |
73 #define VIDEO_ID 0xe0 | |
336 | 74 #define AC3_ID 0x80 |
75 #define LPCM_ID 0xa0 | |
0 | 76 |
356
72c7cf2f3a7a
CONFIG_ENCODERS fix by (Ronald Bultje <rbultje at ronald dot bitfreak dot net>)
michael
parents:
355
diff
changeset
|
77 static const int lpcm_freq_tab[4] = { 48000, 96000, 44100, 32000 }; |
72c7cf2f3a7a
CONFIG_ENCODERS fix by (Ronald Bultje <rbultje at ronald dot bitfreak dot net>)
michael
parents:
355
diff
changeset
|
78 |
277
a313e1080322
disable encoders where appropriate (patch courtesy of BERO
melanson
parents:
276
diff
changeset
|
79 #ifdef CONFIG_ENCODERS |
0 | 80 extern AVOutputFormat mpeg1system_mux; |
81 extern AVOutputFormat mpeg1vcd_mux; | |
82 extern AVOutputFormat mpeg2vob_mux; | |
83 | |
84 static int put_pack_header(AVFormatContext *ctx, | |
65 | 85 uint8_t *buf, int64_t timestamp) |
0 | 86 { |
87 MpegMuxContext *s = ctx->priv_data; | |
88 PutBitContext pb; | |
89 | |
276 | 90 init_put_bits(&pb, buf, 128); |
0 | 91 |
92 put_bits(&pb, 32, PACK_START_CODE); | |
93 if (s->is_mpeg2) { | |
174
7d56e9f83fdb
Write correct MPEG2-PS streams patch by (mru at users dot sourceforge dot net (Mns Rullgrd))
michaelni
parents:
165
diff
changeset
|
94 put_bits(&pb, 2, 0x1); |
0 | 95 } else { |
96 put_bits(&pb, 4, 0x2); | |
97 } | |
65 | 98 put_bits(&pb, 3, (uint32_t)((timestamp >> 30) & 0x07)); |
0 | 99 put_bits(&pb, 1, 1); |
65 | 100 put_bits(&pb, 15, (uint32_t)((timestamp >> 15) & 0x7fff)); |
0 | 101 put_bits(&pb, 1, 1); |
65 | 102 put_bits(&pb, 15, (uint32_t)((timestamp) & 0x7fff)); |
0 | 103 put_bits(&pb, 1, 1); |
104 if (s->is_mpeg2) { | |
105 /* clock extension */ | |
106 put_bits(&pb, 9, 0); | |
107 } | |
108 put_bits(&pb, 1, 1); | |
109 put_bits(&pb, 22, s->mux_rate); | |
110 put_bits(&pb, 1, 1); | |
111 if (s->is_mpeg2) { | |
357
f4f573c7dc56
Patch for MPEG-2 VOB headers by (Jimmy Blair <blueskyjb at verizon dot net>)
michael
parents:
356
diff
changeset
|
112 put_bits(&pb, 1, 1); |
0 | 113 put_bits(&pb, 5, 0x1f); /* reserved */ |
114 put_bits(&pb, 3, 0); /* stuffing length */ | |
115 } | |
116 flush_put_bits(&pb); | |
117 return pbBufPtr(&pb) - pb.buf; | |
118 } | |
119 | |
65 | 120 static int put_system_header(AVFormatContext *ctx, uint8_t *buf) |
0 | 121 { |
122 MpegMuxContext *s = ctx->priv_data; | |
123 int size, rate_bound, i, private_stream_coded, id; | |
124 PutBitContext pb; | |
125 | |
276 | 126 init_put_bits(&pb, buf, 128); |
0 | 127 |
128 put_bits(&pb, 32, SYSTEM_HEADER_START_CODE); | |
129 put_bits(&pb, 16, 0); | |
130 put_bits(&pb, 1, 1); | |
131 | |
132 rate_bound = s->mux_rate; /* maximum bit rate of the multiplexed stream */ | |
133 put_bits(&pb, 22, rate_bound); | |
134 put_bits(&pb, 1, 1); /* marker */ | |
135 put_bits(&pb, 6, s->audio_bound); | |
136 | |
137 put_bits(&pb, 1, 1); /* variable bitrate */ | |
138 put_bits(&pb, 1, 1); /* non constrainted bit stream */ | |
139 | |
140 put_bits(&pb, 1, 0); /* audio locked */ | |
141 put_bits(&pb, 1, 0); /* video locked */ | |
142 put_bits(&pb, 1, 1); /* marker */ | |
143 | |
144 put_bits(&pb, 5, s->video_bound); | |
145 put_bits(&pb, 8, 0xff); /* reserved byte */ | |
146 | |
147 /* audio stream info */ | |
148 private_stream_coded = 0; | |
149 for(i=0;i<ctx->nb_streams;i++) { | |
150 StreamInfo *stream = ctx->streams[i]->priv_data; | |
151 id = stream->id; | |
152 if (id < 0xc0) { | |
153 /* special case for private streams (AC3 use that) */ | |
154 if (private_stream_coded) | |
155 continue; | |
156 private_stream_coded = 1; | |
157 id = 0xbd; | |
158 } | |
159 put_bits(&pb, 8, id); /* stream ID */ | |
160 put_bits(&pb, 2, 3); | |
161 if (id < 0xe0) { | |
162 /* audio */ | |
163 put_bits(&pb, 1, 0); | |
164 put_bits(&pb, 13, stream->max_buffer_size / 128); | |
165 } else { | |
166 /* video */ | |
167 put_bits(&pb, 1, 1); | |
168 put_bits(&pb, 13, stream->max_buffer_size / 1024); | |
169 } | |
170 } | |
171 flush_put_bits(&pb); | |
172 size = pbBufPtr(&pb) - pb.buf; | |
173 /* patch packet size */ | |
174 buf[4] = (size - 6) >> 8; | |
175 buf[5] = (size - 6) & 0xff; | |
176 | |
177 return size; | |
178 } | |
179 | |
335
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
180 static int get_system_header_size(AVFormatContext *ctx) |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
181 { |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
182 int buf_index, i, private_stream_coded; |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
183 StreamInfo *stream; |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
184 |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
185 buf_index = 12; |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
186 private_stream_coded = 0; |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
187 for(i=0;i<ctx->nb_streams;i++) { |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
188 stream = ctx->streams[i]->priv_data; |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
189 if (stream->id < 0xc0) { |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
190 if (private_stream_coded) |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
191 continue; |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
192 private_stream_coded = 1; |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
193 } |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
194 buf_index += 3; |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
195 } |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
196 return buf_index; |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
197 } |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
198 |
0 | 199 static int mpeg_mux_init(AVFormatContext *ctx) |
200 { | |
201 MpegMuxContext *s = ctx->priv_data; | |
336 | 202 int bitrate, i, mpa_id, mpv_id, ac3_id, lpcm_id, j; |
0 | 203 AVStream *st; |
204 StreamInfo *stream; | |
205 | |
206 s->packet_number = 0; | |
207 s->is_vcd = (ctx->oformat == &mpeg1vcd_mux); | |
208 s->is_mpeg2 = (ctx->oformat == &mpeg2vob_mux); | |
209 | |
210 if (s->is_vcd) | |
211 s->packet_size = 2324; /* VCD packet size */ | |
212 else | |
213 s->packet_size = 2048; | |
214 | |
215 s->audio_bound = 0; | |
216 s->video_bound = 0; | |
217 mpa_id = AUDIO_ID; | |
336 | 218 ac3_id = AC3_ID; |
0 | 219 mpv_id = VIDEO_ID; |
336 | 220 lpcm_id = LPCM_ID; |
331
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
221 s->scr_stream_index = -1; |
0 | 222 for(i=0;i<ctx->nb_streams;i++) { |
223 st = ctx->streams[i]; | |
224 stream = av_mallocz(sizeof(StreamInfo)); | |
225 if (!stream) | |
226 goto fail; | |
227 st->priv_data = stream; | |
228 | |
229 switch(st->codec.codec_type) { | |
230 case CODEC_TYPE_AUDIO: | |
336 | 231 if (st->codec.codec_id == CODEC_ID_AC3) { |
0 | 232 stream->id = ac3_id++; |
336 | 233 } else if (st->codec.codec_id == CODEC_ID_PCM_S16BE) { |
234 stream->id = lpcm_id++; | |
235 for(j = 0; j < 4; j++) { | |
236 if (lpcm_freq_tab[j] == st->codec.sample_rate) | |
237 break; | |
238 } | |
239 if (j == 4) | |
240 goto fail; | |
241 if (st->codec.channels > 8) | |
242 return -1; | |
243 stream->lpcm_header[0] = 0x0c; | |
244 stream->lpcm_header[1] = (st->codec.channels - 1) | (j << 4); | |
245 stream->lpcm_header[2] = 0x80; | |
246 stream->lpcm_align = st->codec.channels * 2; | |
247 } else { | |
0 | 248 stream->id = mpa_id++; |
336 | 249 } |
0 | 250 stream->max_buffer_size = 4 * 1024; |
251 s->audio_bound++; | |
252 break; | |
253 case CODEC_TYPE_VIDEO: | |
331
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
254 /* by default, video is used for the SCR computation */ |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
255 if (s->scr_stream_index == -1) |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
256 s->scr_stream_index = i; |
0 | 257 stream->id = mpv_id++; |
258 stream->max_buffer_size = 46 * 1024; | |
259 s->video_bound++; | |
260 break; | |
261 default: | |
262 av_abort(); | |
263 } | |
264 } | |
331
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
265 /* if no SCR, use first stream (audio) */ |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
266 if (s->scr_stream_index == -1) |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
267 s->scr_stream_index = 0; |
0 | 268 |
269 /* we increase slightly the bitrate to take into account the | |
270 headers. XXX: compute it exactly */ | |
271 bitrate = 2000; | |
272 for(i=0;i<ctx->nb_streams;i++) { | |
273 st = ctx->streams[i]; | |
274 bitrate += st->codec.bit_rate; | |
275 } | |
276 s->mux_rate = (bitrate + (8 * 50) - 1) / (8 * 50); | |
277 | |
278 if (s->is_vcd || s->is_mpeg2) | |
279 /* every packet */ | |
280 s->pack_header_freq = 1; | |
281 else | |
282 /* every 2 seconds */ | |
283 s->pack_header_freq = 2 * bitrate / s->packet_size / 8; | |
291
b19f70a6d60f
1/0 fix by (Tim Allen <tim at proximity dot com dot au>)
michael
parents:
277
diff
changeset
|
284 |
b19f70a6d60f
1/0 fix by (Tim Allen <tim at proximity dot com dot au>)
michael
parents:
277
diff
changeset
|
285 /* the above seems to make pack_header_freq zero sometimes */ |
b19f70a6d60f
1/0 fix by (Tim Allen <tim at proximity dot com dot au>)
michael
parents:
277
diff
changeset
|
286 if (s->pack_header_freq == 0) |
b19f70a6d60f
1/0 fix by (Tim Allen <tim at proximity dot com dot au>)
michael
parents:
277
diff
changeset
|
287 s->pack_header_freq = 1; |
0 | 288 |
289 if (s->is_mpeg2) | |
290 /* every 200 packets. Need to look at the spec. */ | |
291 s->system_header_freq = s->pack_header_freq * 40; | |
292 else if (s->is_vcd) | |
293 /* every 40 packets, this is my invention */ | |
294 s->system_header_freq = s->pack_header_freq * 40; | |
295 else | |
296 s->system_header_freq = s->pack_header_freq * 5; | |
297 | |
298 for(i=0;i<ctx->nb_streams;i++) { | |
299 stream = ctx->streams[i]->priv_data; | |
300 stream->buffer_ptr = 0; | |
301 stream->packet_number = 0; | |
331
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
302 stream->start_pts = AV_NOPTS_VALUE; |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
303 stream->start_dts = AV_NOPTS_VALUE; |
0 | 304 } |
335
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
305 s->system_header_size = get_system_header_size(ctx); |
331
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
306 s->last_scr = 0; |
0 | 307 return 0; |
308 fail: | |
309 for(i=0;i<ctx->nb_streams;i++) { | |
310 av_free(ctx->streams[i]->priv_data); | |
311 } | |
312 return -ENOMEM; | |
313 } | |
314 | |
331
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
315 static inline void put_timestamp(ByteIOContext *pb, int id, int64_t timestamp) |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
316 { |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
317 put_byte(pb, |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
318 (id << 4) | |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
319 (((timestamp >> 30) & 0x07) << 1) | |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
320 1); |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
321 put_be16(pb, (uint16_t)((((timestamp >> 15) & 0x7fff) << 1) | 1)); |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
322 put_be16(pb, (uint16_t)((((timestamp) & 0x7fff) << 1) | 1)); |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
323 } |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
324 |
335
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
325 |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
326 /* return the exact available payload size for the next packet for |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
327 stream 'stream_index'. 'pts' and 'dts' are only used to know if |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
328 timestamps are needed in the packet header. */ |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
329 static int get_packet_payload_size(AVFormatContext *ctx, int stream_index, |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
330 int64_t pts, int64_t dts) |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
331 { |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
332 MpegMuxContext *s = ctx->priv_data; |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
333 int buf_index; |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
334 StreamInfo *stream; |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
335 |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
336 buf_index = 0; |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
337 if (((s->packet_number % s->pack_header_freq) == 0)) { |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
338 /* pack header size */ |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
339 if (s->is_mpeg2) |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
340 buf_index += 14; |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
341 else |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
342 buf_index += 12; |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
343 if ((s->packet_number % s->system_header_freq) == 0) |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
344 buf_index += s->system_header_size; |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
345 } |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
346 |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
347 /* packet header size */ |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
348 buf_index += 6; |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
349 if (s->is_mpeg2) |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
350 buf_index += 3; |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
351 if (pts != AV_NOPTS_VALUE) { |
337 | 352 if (dts != pts) |
335
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
353 buf_index += 5 + 5; |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
354 else |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
355 buf_index += 5; |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
356 } else { |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
357 if (!s->is_mpeg2) |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
358 buf_index++; |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
359 } |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
360 |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
361 stream = ctx->streams[stream_index]->priv_data; |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
362 if (stream->id < 0xc0) { |
336 | 363 /* AC3/LPCM private data header */ |
335
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
364 buf_index += 4; |
336 | 365 if (stream->id >= 0xa0) { |
366 int n; | |
367 buf_index += 3; | |
368 /* NOTE: we round the payload size to an integer number of | |
369 LPCM samples */ | |
370 n = (s->packet_size - buf_index) % stream->lpcm_align; | |
371 if (n) | |
372 buf_index += (stream->lpcm_align - n); | |
373 } | |
335
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
374 } |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
375 return s->packet_size - buf_index; |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
376 } |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
377 |
0 | 378 /* flush the packet on stream stream_index */ |
331
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
379 static void flush_packet(AVFormatContext *ctx, int stream_index, |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
380 int64_t pts, int64_t dts, int64_t scr) |
0 | 381 { |
382 MpegMuxContext *s = ctx->priv_data; | |
383 StreamInfo *stream = ctx->streams[stream_index]->priv_data; | |
65 | 384 uint8_t *buf_ptr; |
335
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
385 int size, payload_size, startcode, id, stuffing_size, i, header_len; |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
386 int packet_size; |
65 | 387 uint8_t buffer[128]; |
0 | 388 |
389 id = stream->id; | |
331
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
390 |
0 | 391 #if 0 |
392 printf("packet ID=%2x PTS=%0.3f\n", | |
331
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
393 id, pts / 90000.0); |
0 | 394 #endif |
395 | |
396 buf_ptr = buffer; | |
397 if (((s->packet_number % s->pack_header_freq) == 0)) { | |
398 /* output pack and systems header if needed */ | |
331
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
399 size = put_pack_header(ctx, buf_ptr, scr); |
0 | 400 buf_ptr += size; |
401 if ((s->packet_number % s->system_header_freq) == 0) { | |
402 size = put_system_header(ctx, buf_ptr); | |
403 buf_ptr += size; | |
404 } | |
405 } | |
406 size = buf_ptr - buffer; | |
407 put_buffer(&ctx->pb, buffer, size); | |
408 | |
409 /* packet header */ | |
410 if (s->is_mpeg2) { | |
331
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
411 header_len = 3; |
0 | 412 } else { |
331
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
413 header_len = 0; |
0 | 414 } |
331
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
415 if (pts != AV_NOPTS_VALUE) { |
337 | 416 if (dts != pts) |
331
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
417 header_len += 5 + 5; |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
418 else |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
419 header_len += 5; |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
420 } else { |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
421 if (!s->is_mpeg2) |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
422 header_len++; |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
423 } |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
424 |
335
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
425 packet_size = s->packet_size - (size + 6); |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
426 payload_size = packet_size - header_len; |
0 | 427 if (id < 0xc0) { |
428 startcode = PRIVATE_STREAM_1; | |
429 payload_size -= 4; | |
336 | 430 if (id >= 0xa0) |
431 payload_size -= 3; | |
0 | 432 } else { |
433 startcode = 0x100 + id; | |
434 } | |
335
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
435 |
0 | 436 stuffing_size = payload_size - stream->buffer_ptr; |
437 if (stuffing_size < 0) | |
438 stuffing_size = 0; | |
439 put_be32(&ctx->pb, startcode); | |
440 | |
335
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
441 put_be16(&ctx->pb, packet_size); |
357
f4f573c7dc56
Patch for MPEG-2 VOB headers by (Jimmy Blair <blueskyjb at verizon dot net>)
michael
parents:
356
diff
changeset
|
442 |
f4f573c7dc56
Patch for MPEG-2 VOB headers by (Jimmy Blair <blueskyjb at verizon dot net>)
michael
parents:
356
diff
changeset
|
443 if (!s->is_mpeg2) |
f4f573c7dc56
Patch for MPEG-2 VOB headers by (Jimmy Blair <blueskyjb at verizon dot net>)
michael
parents:
356
diff
changeset
|
444 for(i=0;i<stuffing_size;i++) |
f4f573c7dc56
Patch for MPEG-2 VOB headers by (Jimmy Blair <blueskyjb at verizon dot net>)
michael
parents:
356
diff
changeset
|
445 put_byte(&ctx->pb, 0xff); |
0 | 446 |
447 if (s->is_mpeg2) { | |
448 put_byte(&ctx->pb, 0x80); /* mpeg2 id */ | |
331
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
449 |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
450 if (pts != AV_NOPTS_VALUE) { |
337 | 451 if (dts != pts) { |
331
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
452 put_byte(&ctx->pb, 0xc0); /* flags */ |
357
f4f573c7dc56
Patch for MPEG-2 VOB headers by (Jimmy Blair <blueskyjb at verizon dot net>)
michael
parents:
356
diff
changeset
|
453 put_byte(&ctx->pb, header_len - 3 + stuffing_size); |
331
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
454 put_timestamp(&ctx->pb, 0x03, pts); |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
455 put_timestamp(&ctx->pb, 0x01, dts); |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
456 } else { |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
457 put_byte(&ctx->pb, 0x80); /* flags */ |
357
f4f573c7dc56
Patch for MPEG-2 VOB headers by (Jimmy Blair <blueskyjb at verizon dot net>)
michael
parents:
356
diff
changeset
|
458 put_byte(&ctx->pb, header_len - 3 + stuffing_size); |
331
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
459 put_timestamp(&ctx->pb, 0x02, pts); |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
460 } |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
461 } else { |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
462 put_byte(&ctx->pb, 0x00); /* flags */ |
357
f4f573c7dc56
Patch for MPEG-2 VOB headers by (Jimmy Blair <blueskyjb at verizon dot net>)
michael
parents:
356
diff
changeset
|
463 put_byte(&ctx->pb, header_len - 3 + stuffing_size); |
331
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
464 } |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
465 } else { |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
466 if (pts != AV_NOPTS_VALUE) { |
337 | 467 if (dts != pts) { |
331
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
468 put_timestamp(&ctx->pb, 0x03, pts); |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
469 put_timestamp(&ctx->pb, 0x01, dts); |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
470 } else { |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
471 put_timestamp(&ctx->pb, 0x02, pts); |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
472 } |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
473 } else { |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
474 put_byte(&ctx->pb, 0x0f); |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
475 } |
0 | 476 } |
477 | |
478 if (startcode == PRIVATE_STREAM_1) { | |
479 put_byte(&ctx->pb, id); | |
336 | 480 if (id >= 0xa0) { |
481 /* LPCM (XXX: check nb_frames) */ | |
482 put_byte(&ctx->pb, 7); | |
483 put_be16(&ctx->pb, 4); /* skip 3 header bytes */ | |
484 put_byte(&ctx->pb, stream->lpcm_header[0]); | |
485 put_byte(&ctx->pb, stream->lpcm_header[1]); | |
486 put_byte(&ctx->pb, stream->lpcm_header[2]); | |
487 } else { | |
488 /* AC3 */ | |
335
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
489 put_byte(&ctx->pb, stream->nb_frames); |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
490 put_be16(&ctx->pb, stream->frame_start_offset); |
0 | 491 } |
492 } | |
493 | |
357
f4f573c7dc56
Patch for MPEG-2 VOB headers by (Jimmy Blair <blueskyjb at verizon dot net>)
michael
parents:
356
diff
changeset
|
494 if (s->is_mpeg2) |
f4f573c7dc56
Patch for MPEG-2 VOB headers by (Jimmy Blair <blueskyjb at verizon dot net>)
michael
parents:
356
diff
changeset
|
495 for(i=0;i<stuffing_size;i++) |
f4f573c7dc56
Patch for MPEG-2 VOB headers by (Jimmy Blair <blueskyjb at verizon dot net>)
michael
parents:
356
diff
changeset
|
496 put_byte(&ctx->pb, 0xff); |
f4f573c7dc56
Patch for MPEG-2 VOB headers by (Jimmy Blair <blueskyjb at verizon dot net>)
michael
parents:
356
diff
changeset
|
497 |
0 | 498 /* output data */ |
499 put_buffer(&ctx->pb, stream->buffer, payload_size - stuffing_size); | |
500 put_flush_packet(&ctx->pb); | |
501 | |
502 s->packet_number++; | |
503 stream->packet_number++; | |
335
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
504 stream->nb_frames = 0; |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
505 stream->frame_start_offset = 0; |
0 | 506 } |
507 | |
337 | 508 /* XXX: move that to upper layer */ |
509 /* XXX: we assume that there are always 'max_b_frames' between | |
510 reference frames. A better solution would be to use the AVFrame pts | |
511 field */ | |
512 static void compute_pts_dts(AVStream *st, int64_t *ppts, int64_t *pdts, | |
513 int64_t timestamp) | |
514 { | |
515 int frame_delay; | |
516 int64_t pts, dts; | |
517 | |
518 if (st->codec.codec_type == CODEC_TYPE_VIDEO && | |
519 st->codec.max_b_frames != 0) { | |
520 frame_delay = (st->codec.frame_rate_base * 90000LL) / | |
521 st->codec.frame_rate; | |
522 if (timestamp == 0) { | |
523 /* specific case for first frame : DTS just before */ | |
524 pts = timestamp; | |
525 dts = timestamp - frame_delay; | |
526 } else { | |
527 timestamp -= frame_delay; | |
528 if (st->codec.coded_frame->pict_type == FF_B_TYPE) { | |
529 /* B frames has identical pts/dts */ | |
530 pts = timestamp; | |
531 dts = timestamp; | |
532 } else { | |
533 /* a reference frame has a pts equal to the dts of the | |
534 _next_ one */ | |
535 dts = timestamp; | |
536 pts = timestamp + (st->codec.max_b_frames + 1) * frame_delay; | |
537 } | |
538 } | |
539 #if 1 | |
540 printf("pts=%0.3f dts=%0.3f pict_type=%c\n", | |
541 pts / 90000.0, dts / 90000.0, | |
542 av_get_pict_type_char(st->codec.coded_frame->pict_type)); | |
543 #endif | |
544 } else { | |
545 pts = timestamp; | |
546 dts = timestamp; | |
547 } | |
548 *ppts = pts & ((1LL << 33) - 1); | |
549 *pdts = dts & ((1LL << 33) - 1); | |
550 } | |
551 | |
0 | 552 static int mpeg_mux_write_packet(AVFormatContext *ctx, int stream_index, |
337 | 553 const uint8_t *buf, int size, |
554 int64_t timestamp) | |
0 | 555 { |
556 MpegMuxContext *s = ctx->priv_data; | |
557 AVStream *st = ctx->streams[stream_index]; | |
558 StreamInfo *stream = st->priv_data; | |
337 | 559 int64_t pts, dts, new_start_pts, new_start_dts; |
335
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
560 int len, avail_size; |
331
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
561 |
337 | 562 compute_pts_dts(st, &pts, &dts, timestamp); |
563 | |
331
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
564 /* XXX: system clock should be computed precisely, especially for |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
565 CBR case. The current mode gives at least something coherent */ |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
566 if (stream_index == s->scr_stream_index) |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
567 s->last_scr = pts; |
0 | 568 |
331
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
569 #if 0 |
337 | 570 printf("%d: pts=%0.3f dts=%0.3f scr=%0.3f\n", |
571 stream_index, | |
572 pts / 90000.0, | |
573 dts / 90000.0, | |
574 s->last_scr / 90000.0); | |
331
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
575 #endif |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
576 |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
577 /* we assume here that pts != AV_NOPTS_VALUE */ |
335
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
578 new_start_pts = stream->start_pts; |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
579 new_start_dts = stream->start_dts; |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
580 |
331
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
581 if (stream->start_pts == AV_NOPTS_VALUE) { |
335
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
582 new_start_pts = pts; |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
583 new_start_dts = dts; |
331
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
584 } |
335
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
585 avail_size = get_packet_payload_size(ctx, stream_index, |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
586 new_start_pts, |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
587 new_start_dts); |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
588 if (stream->buffer_ptr >= avail_size) { |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
589 /* unlikely case: outputing the pts or dts increase the packet |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
590 size so that we cannot write the start of the next |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
591 packet. In this case, we must flush the current packet with |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
592 padding */ |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
593 flush_packet(ctx, stream_index, |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
594 stream->start_pts, stream->start_dts, s->last_scr); |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
595 stream->buffer_ptr = 0; |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
596 } |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
597 stream->start_pts = new_start_pts; |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
598 stream->start_dts = new_start_dts; |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
599 stream->nb_frames++; |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
600 if (stream->frame_start_offset == 0) |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
601 stream->frame_start_offset = stream->buffer_ptr; |
0 | 602 while (size > 0) { |
335
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
603 avail_size = get_packet_payload_size(ctx, stream_index, |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
604 stream->start_pts, |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
605 stream->start_dts); |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
606 len = avail_size - stream->buffer_ptr; |
0 | 607 if (len > size) |
608 len = size; | |
609 memcpy(stream->buffer + stream->buffer_ptr, buf, len); | |
610 stream->buffer_ptr += len; | |
611 buf += len; | |
612 size -= len; | |
335
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
613 if (stream->buffer_ptr >= avail_size) { |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
614 /* if packet full, we send it now */ |
331
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
615 flush_packet(ctx, stream_index, |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
616 stream->start_pts, stream->start_dts, s->last_scr); |
335
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
617 stream->buffer_ptr = 0; |
331
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
618 /* Make sure only the FIRST pes packet for this frame has |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
619 a timestamp */ |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
620 stream->start_pts = AV_NOPTS_VALUE; |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
621 stream->start_dts = AV_NOPTS_VALUE; |
0 | 622 } |
623 } | |
335
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
624 |
0 | 625 return 0; |
626 } | |
627 | |
628 static int mpeg_mux_end(AVFormatContext *ctx) | |
629 { | |
331
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
630 MpegMuxContext *s = ctx->priv_data; |
0 | 631 StreamInfo *stream; |
632 int i; | |
633 | |
634 /* flush each packet */ | |
635 for(i=0;i<ctx->nb_streams;i++) { | |
636 stream = ctx->streams[i]->priv_data; | |
335
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
637 if (stream->buffer_ptr > 0) { |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
638 /* NOTE: we can always write the remaining data as it was |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
639 tested before in mpeg_mux_write_packet() */ |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
640 flush_packet(ctx, i, stream->start_pts, stream->start_dts, |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
641 s->last_scr); |
0 | 642 } |
643 } | |
644 | |
242 | 645 /* End header according to MPEG1 systems standard. We do not write |
646 it as it is usually not needed by decoders and because it | |
647 complicates MPEG stream concatenation. */ | |
0 | 648 //put_be32(&ctx->pb, ISO_11172_END_CODE); |
649 //put_flush_packet(&ctx->pb); | |
237
35231c0be8e5
memleak fix by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michaelni
parents:
210
diff
changeset
|
650 |
35231c0be8e5
memleak fix by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michaelni
parents:
210
diff
changeset
|
651 for(i=0;i<ctx->nb_streams;i++) |
35231c0be8e5
memleak fix by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michaelni
parents:
210
diff
changeset
|
652 av_freep(&ctx->streams[i]->priv_data); |
35231c0be8e5
memleak fix by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michaelni
parents:
210
diff
changeset
|
653 |
0 | 654 return 0; |
655 } | |
277
a313e1080322
disable encoders where appropriate (patch courtesy of BERO
melanson
parents:
276
diff
changeset
|
656 #endif //CONFIG_ENCODERS |
0 | 657 |
658 /*********************************************/ | |
659 /* demux code */ | |
660 | |
661 #define MAX_SYNC_SIZE 100000 | |
662 | |
663 static int mpegps_probe(AVProbeData *p) | |
664 { | |
165
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
665 int code, c, i; |
0 | 666 |
165
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
667 code = 0xff; |
0 | 668 /* we search the first start code. If it is a packet start code, |
669 then we decide it is mpeg ps. We do not send highest value to | |
670 give a chance to mpegts */ | |
49 | 671 /* NOTE: the search range was restricted to avoid too many false |
672 detections */ | |
673 | |
674 if (p->buf_size < 6) | |
675 return 0; | |
165
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
676 |
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
677 for (i = 0; i < 20; i++) { |
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
678 c = p->buf[i]; |
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
679 code = (code << 8) | c; |
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
680 if ((code & 0xffffff00) == 0x100) { |
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
681 if (code == PACK_START_CODE || |
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
682 code == SYSTEM_HEADER_START_CODE || |
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
683 (code >= 0x1e0 && code <= 0x1ef) || |
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
684 (code >= 0x1c0 && code <= 0x1df) || |
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
685 code == PRIVATE_STREAM_2 || |
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
686 code == PROGRAM_STREAM_MAP || |
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
687 code == PRIVATE_STREAM_1 || |
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
688 code == PADDING_STREAM) |
210 | 689 return AVPROBE_SCORE_MAX - 2; |
165
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
690 else |
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
691 return 0; |
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
692 } |
0 | 693 } |
694 return 0; | |
695 } | |
696 | |
697 | |
698 typedef struct MpegDemuxContext { | |
699 int header_state; | |
700 } MpegDemuxContext; | |
701 | |
310 | 702 static int mpegps_read_header(AVFormatContext *s, |
703 AVFormatParameters *ap) | |
704 { | |
705 MpegDemuxContext *m = s->priv_data; | |
706 m->header_state = 0xff; | |
707 s->ctx_flags |= AVFMTCTX_NOHEADER; | |
708 | |
709 /* no need to do more */ | |
710 return 0; | |
711 } | |
712 | |
713 static int64_t get_pts(ByteIOContext *pb, int c) | |
714 { | |
715 int64_t pts; | |
716 int val; | |
717 | |
718 if (c < 0) | |
719 c = get_byte(pb); | |
720 pts = (int64_t)((c >> 1) & 0x07) << 30; | |
721 val = get_be16(pb); | |
722 pts |= (int64_t)(val >> 1) << 15; | |
723 val = get_be16(pb); | |
724 pts |= (int64_t)(val >> 1); | |
725 return pts; | |
726 } | |
727 | |
728 static int find_next_start_code(ByteIOContext *pb, int *size_ptr, | |
729 uint32_t *header_state) | |
0 | 730 { |
731 unsigned int state, v; | |
732 int val, n; | |
733 | |
734 state = *header_state; | |
735 n = *size_ptr; | |
736 while (n > 0) { | |
737 if (url_feof(pb)) | |
738 break; | |
739 v = get_byte(pb); | |
740 n--; | |
741 if (state == 0x000001) { | |
742 state = ((state << 8) | v) & 0xffffff; | |
743 val = state; | |
744 goto found; | |
745 } | |
746 state = ((state << 8) | v) & 0xffffff; | |
747 } | |
748 val = -1; | |
749 found: | |
750 *header_state = state; | |
751 *size_ptr = n; | |
752 return val; | |
753 } | |
754 | |
310 | 755 /* XXX: optimize */ |
756 static int find_prev_start_code(ByteIOContext *pb, int *size_ptr) | |
0 | 757 { |
310 | 758 int64_t pos, pos_start; |
759 int max_size, start_code; | |
760 | |
761 max_size = *size_ptr; | |
762 pos_start = url_ftell(pb); | |
763 | |
764 /* in order to go faster, we fill the buffer */ | |
765 pos = pos_start - 16386; | |
766 if (pos < 0) | |
767 pos = 0; | |
768 url_fseek(pb, pos, SEEK_SET); | |
769 get_byte(pb); | |
293
62cec412a186
make AVFMT_NOHEADER flag dynamic - added av_open_input_stream()
bellard
parents:
291
diff
changeset
|
770 |
310 | 771 pos = pos_start; |
772 for(;;) { | |
773 pos--; | |
774 if (pos < 0 || (pos_start - pos) >= max_size) { | |
775 start_code = -1; | |
776 goto the_end; | |
777 } | |
778 url_fseek(pb, pos, SEEK_SET); | |
779 start_code = get_be32(pb); | |
780 if ((start_code & 0xffffff00) == 0x100) | |
781 break; | |
782 } | |
783 the_end: | |
784 *size_ptr = pos_start - pos; | |
785 return start_code; | |
0 | 786 } |
787 | |
310 | 788 /* read the next (or previous) PES header. Return its position in ppos |
789 (if not NULL), and its start code, pts and dts. | |
790 */ | |
791 static int mpegps_read_pes_header(AVFormatContext *s, | |
792 int64_t *ppos, int *pstart_code, | |
793 int64_t *ppts, int64_t *pdts, int find_next) | |
0 | 794 { |
795 MpegDemuxContext *m = s->priv_data; | |
310 | 796 int len, size, startcode, c, flags, header_len; |
797 int64_t pts, dts, last_pos; | |
0 | 798 |
310 | 799 last_pos = -1; |
0 | 800 redo: |
310 | 801 if (find_next) { |
802 /* next start code (should be immediately after) */ | |
803 m->header_state = 0xff; | |
804 size = MAX_SYNC_SIZE; | |
805 startcode = find_next_start_code(&s->pb, &size, &m->header_state); | |
806 } else { | |
807 if (last_pos >= 0) | |
808 url_fseek(&s->pb, last_pos, SEEK_SET); | |
809 size = MAX_SYNC_SIZE; | |
810 startcode = find_prev_start_code(&s->pb, &size); | |
811 last_pos = url_ftell(&s->pb) - 4; | |
812 } | |
0 | 813 //printf("startcode=%x pos=0x%Lx\n", startcode, url_ftell(&s->pb)); |
814 if (startcode < 0) | |
815 return -EIO; | |
816 if (startcode == PACK_START_CODE) | |
817 goto redo; | |
818 if (startcode == SYSTEM_HEADER_START_CODE) | |
819 goto redo; | |
820 if (startcode == PADDING_STREAM || | |
821 startcode == PRIVATE_STREAM_2) { | |
822 /* skip them */ | |
823 len = get_be16(&s->pb); | |
824 url_fskip(&s->pb, len); | |
825 goto redo; | |
826 } | |
827 /* find matching stream */ | |
828 if (!((startcode >= 0x1c0 && startcode <= 0x1df) || | |
829 (startcode >= 0x1e0 && startcode <= 0x1ef) || | |
830 (startcode == 0x1bd))) | |
831 goto redo; | |
310 | 832 if (ppos) { |
833 *ppos = url_ftell(&s->pb) - 4; | |
834 } | |
0 | 835 len = get_be16(&s->pb); |
836 pts = AV_NOPTS_VALUE; | |
837 dts = AV_NOPTS_VALUE; | |
838 /* stuffing */ | |
839 for(;;) { | |
310 | 840 if (len < 1) |
841 goto redo; | |
0 | 842 c = get_byte(&s->pb); |
843 len--; | |
844 /* XXX: for mpeg1, should test only bit 7 */ | |
845 if (c != 0xff) | |
846 break; | |
847 } | |
848 if ((c & 0xc0) == 0x40) { | |
849 /* buffer scale & size */ | |
310 | 850 if (len < 2) |
851 goto redo; | |
0 | 852 get_byte(&s->pb); |
853 c = get_byte(&s->pb); | |
854 len -= 2; | |
855 } | |
856 if ((c & 0xf0) == 0x20) { | |
310 | 857 if (len < 4) |
858 goto redo; | |
859 dts = pts = get_pts(&s->pb, c); | |
0 | 860 len -= 4; |
861 } else if ((c & 0xf0) == 0x30) { | |
310 | 862 if (len < 9) |
863 goto redo; | |
0 | 864 pts = get_pts(&s->pb, c); |
865 dts = get_pts(&s->pb, -1); | |
866 len -= 9; | |
867 } else if ((c & 0xc0) == 0x80) { | |
868 /* mpeg 2 PES */ | |
869 if ((c & 0x30) != 0) { | |
310 | 870 /* Encrypted multiplex not handled */ |
871 goto redo; | |
0 | 872 } |
873 flags = get_byte(&s->pb); | |
874 header_len = get_byte(&s->pb); | |
875 len -= 2; | |
876 if (header_len > len) | |
877 goto redo; | |
878 if ((flags & 0xc0) == 0x80) { | |
310 | 879 dts = pts = get_pts(&s->pb, -1); |
880 if (header_len < 5) | |
881 goto redo; | |
0 | 882 header_len -= 5; |
883 len -= 5; | |
884 } if ((flags & 0xc0) == 0xc0) { | |
885 pts = get_pts(&s->pb, -1); | |
886 dts = get_pts(&s->pb, -1); | |
310 | 887 if (header_len < 10) |
888 goto redo; | |
0 | 889 header_len -= 10; |
890 len -= 10; | |
891 } | |
892 len -= header_len; | |
893 while (header_len > 0) { | |
894 get_byte(&s->pb); | |
895 header_len--; | |
896 } | |
897 } | |
898 if (startcode == 0x1bd) { | |
310 | 899 if (len < 1) |
900 goto redo; | |
0 | 901 startcode = get_byte(&s->pb); |
902 len--; | |
903 if (startcode >= 0x80 && startcode <= 0xbf) { | |
904 /* audio: skip header */ | |
310 | 905 if (len < 3) |
906 goto redo; | |
0 | 907 get_byte(&s->pb); |
908 get_byte(&s->pb); | |
909 get_byte(&s->pb); | |
910 len -= 3; | |
911 } | |
912 } | |
346
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
913 if(dts != AV_NOPTS_VALUE && ppos){ |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
914 int i; |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
915 for(i=0; i<s->nb_streams; i++){ |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
916 if(startcode == s->streams[i]->id) { |
354
6770ca07abe2
store searched distance in index, so we dont waste time searching for keyframes where we already searched
michael
parents:
346
diff
changeset
|
917 av_add_index_entry(s->streams[i], *ppos, dts, 0, 0 /* FIXME keyframe? */); |
346
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
918 } |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
919 } |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
920 } |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
921 |
310 | 922 *pstart_code = startcode; |
923 *ppts = pts; | |
924 *pdts = dts; | |
925 return len; | |
926 } | |
927 | |
928 static int mpegps_read_packet(AVFormatContext *s, | |
929 AVPacket *pkt) | |
930 { | |
931 AVStream *st; | |
932 int len, startcode, i, type, codec_id; | |
346
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
933 int64_t pts, dts, dummy_pos; //dummy_pos is needed for the index building to work |
310 | 934 |
935 redo: | |
346
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
936 len = mpegps_read_pes_header(s, &dummy_pos, &startcode, &pts, &dts, 1); |
310 | 937 if (len < 0) |
938 return len; | |
331
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
939 |
0 | 940 /* now find stream */ |
941 for(i=0;i<s->nb_streams;i++) { | |
942 st = s->streams[i]; | |
943 if (st->id == startcode) | |
944 goto found; | |
945 } | |
946 if (startcode >= 0x1e0 && startcode <= 0x1ef) { | |
947 type = CODEC_TYPE_VIDEO; | |
335
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
948 codec_id = CODEC_ID_MPEG2VIDEO; |
0 | 949 } else if (startcode >= 0x1c0 && startcode <= 0x1df) { |
950 type = CODEC_TYPE_AUDIO; | |
951 codec_id = CODEC_ID_MP2; | |
952 } else if (startcode >= 0x80 && startcode <= 0x9f) { | |
953 type = CODEC_TYPE_AUDIO; | |
954 codec_id = CODEC_ID_AC3; | |
41 | 955 } else if (startcode >= 0xa0 && startcode <= 0xbf) { |
956 type = CODEC_TYPE_AUDIO; | |
957 codec_id = CODEC_ID_PCM_S16BE; | |
0 | 958 } else { |
959 skip: | |
960 /* skip packet */ | |
961 url_fskip(&s->pb, len); | |
962 goto redo; | |
963 } | |
964 /* no stream found: add a new stream */ | |
965 st = av_new_stream(s, startcode); | |
966 if (!st) | |
967 goto skip; | |
968 st->codec.codec_type = type; | |
969 st->codec.codec_id = codec_id; | |
310 | 970 if (codec_id != CODEC_ID_PCM_S16BE) |
971 st->need_parsing = 1; | |
0 | 972 found: |
41 | 973 if (startcode >= 0xa0 && startcode <= 0xbf) { |
974 int b1, freq; | |
975 | |
976 /* for LPCM, we just skip the header and consider it is raw | |
977 audio data */ | |
978 if (len <= 3) | |
979 goto skip; | |
980 get_byte(&s->pb); /* emphasis (1), muse(1), reserved(1), frame number(5) */ | |
981 b1 = get_byte(&s->pb); /* quant (2), freq(2), reserved(1), channels(3) */ | |
982 get_byte(&s->pb); /* dynamic range control (0x80 = off) */ | |
983 len -= 3; | |
984 freq = (b1 >> 4) & 3; | |
985 st->codec.sample_rate = lpcm_freq_tab[freq]; | |
986 st->codec.channels = 1 + (b1 & 7); | |
987 st->codec.bit_rate = st->codec.channels * st->codec.sample_rate * 2; | |
988 } | |
0 | 989 av_new_packet(pkt, len); |
990 get_buffer(&s->pb, pkt->data, pkt->size); | |
991 pkt->pts = pts; | |
310 | 992 pkt->dts = dts; |
0 | 993 pkt->stream_index = st->index; |
331
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
994 #if 0 |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
995 printf("%d: pts=%0.3f dts=%0.3f\n", |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
996 pkt->stream_index, pkt->pts / 90000.0, pkt->dts / 90000.0); |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
997 #endif |
0 | 998 return 0; |
999 } | |
1000 | |
1001 static int mpegps_read_close(AVFormatContext *s) | |
1002 { | |
1003 return 0; | |
1004 } | |
1005 | |
310 | 1006 static int64_t mpegps_read_dts(AVFormatContext *s, int stream_index, |
1007 int64_t *ppos, int find_next) | |
1008 { | |
1009 int len, startcode; | |
1010 int64_t pos, pts, dts; | |
1011 | |
1012 pos = *ppos; | |
1013 #ifdef DEBUG_SEEK | |
1014 printf("read_dts: pos=0x%llx next=%d -> ", pos, find_next); | |
1015 #endif | |
1016 url_fseek(&s->pb, pos, SEEK_SET); | |
1017 for(;;) { | |
1018 len = mpegps_read_pes_header(s, &pos, &startcode, &pts, &dts, find_next); | |
1019 if (len < 0) { | |
1020 #ifdef DEBUG_SEEK | |
1021 printf("none (ret=%d)\n", len); | |
1022 #endif | |
1023 return AV_NOPTS_VALUE; | |
1024 } | |
1025 if (startcode == s->streams[stream_index]->id && | |
1026 dts != AV_NOPTS_VALUE) { | |
1027 break; | |
1028 } | |
1029 if (find_next) { | |
1030 url_fskip(&s->pb, len); | |
1031 } else { | |
1032 url_fseek(&s->pb, pos, SEEK_SET); | |
1033 } | |
1034 } | |
1035 #ifdef DEBUG_SEEK | |
1036 printf("pos=0x%llx dts=0x%llx %0.3f\n", pos, dts, dts / 90000.0); | |
1037 #endif | |
1038 *ppos = pos; | |
1039 return dts; | |
1040 } | |
1041 | |
1042 static int mpegps_read_seek(AVFormatContext *s, | |
1043 int stream_index, int64_t timestamp) | |
1044 { | |
355 | 1045 int64_t pos_min, pos_max, pos, pos_limit; |
310 | 1046 int64_t dts_min, dts_max, dts; |
355 | 1047 int index, no_change; |
346
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1048 AVStream *st; |
310 | 1049 |
1050 timestamp = (timestamp * 90000) / AV_TIME_BASE; | |
1051 | |
1052 #ifdef DEBUG_SEEK | |
1053 printf("read_seek: %d %0.3f\n", stream_index, timestamp / 90000.0); | |
1054 #endif | |
1055 | |
1056 /* XXX: find stream_index by looking at the first PES packet found */ | |
1057 if (stream_index < 0) { | |
346
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1058 stream_index = av_find_default_stream_index(s); |
310 | 1059 if (stream_index < 0) |
1060 return -1; | |
1061 } | |
346
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1062 |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1063 dts_max= |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1064 dts_min= AV_NOPTS_VALUE; |
355 | 1065 pos_limit= -1; //gcc falsely says it may be uninitalized |
346
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1066 |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1067 st= s->streams[stream_index]; |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1068 if(st->index_entries){ |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1069 AVIndexEntry *e; |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1070 |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1071 index= av_index_search_timestamp(st, timestamp); |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1072 e= &st->index_entries[index]; |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1073 if(e->timestamp <= timestamp){ |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1074 pos_min= e->pos; |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1075 dts_min= e->timestamp; |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1076 #ifdef DEBUG_SEEK |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1077 printf("unsing cached pos_min=0x%llx dts_min=%0.3f\n", |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1078 pos_min,dts_min / 90000.0); |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1079 #endif |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1080 }else{ |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1081 assert(index==0); |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1082 } |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1083 index++; |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1084 if(index < st->nb_index_entries){ |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1085 e= &st->index_entries[index]; |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1086 assert(e->timestamp >= timestamp); |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1087 pos_max= e->pos; |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1088 dts_max= e->timestamp; |
355 | 1089 pos_limit= pos_max - e->min_distance; |
346
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1090 #ifdef DEBUG_SEEK |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1091 printf("unsing cached pos_max=0x%llx dts_max=%0.3f\n", |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1092 pos_max,dts_max / 90000.0); |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1093 #endif |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1094 } |
310 | 1095 } |
346
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1096 |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1097 if(dts_min == AV_NOPTS_VALUE){ |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1098 pos_min = 0; |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1099 dts_min = mpegps_read_dts(s, stream_index, &pos_min, 1); |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1100 if (dts_min == AV_NOPTS_VALUE) { |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1101 /* we can reach this case only if no PTS are present in |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1102 the whole stream */ |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1103 return -1; |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1104 } |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1105 } |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1106 if(dts_max == AV_NOPTS_VALUE){ |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1107 pos_max = url_filesize(url_fileno(&s->pb)) - 1; |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1108 dts_max = mpegps_read_dts(s, stream_index, &pos_max, 0); |
355 | 1109 pos_limit= pos_max; |
346
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
1110 } |
355 | 1111 |
1112 no_change=0; | |
1113 while (pos_min < pos_limit) { | |
310 | 1114 #ifdef DEBUG_SEEK |
1115 printf("pos_min=0x%llx pos_max=0x%llx dts_min=%0.3f dts_max=%0.3f\n", | |
1116 pos_min, pos_max, | |
1117 dts_min / 90000.0, dts_max / 90000.0); | |
1118 #endif | |
355 | 1119 int64_t start_pos; |
1120 assert(pos_limit <= pos_max); | |
1121 | |
1122 if(no_change==0){ | |
1123 int64_t approximate_keyframe_distance= pos_max - pos_limit; | |
1124 // interpolate position (better than dichotomy) | |
1125 pos = (int64_t)((double)(pos_max - pos_min) * | |
310 | 1126 (double)(timestamp - dts_min) / |
355 | 1127 (double)(dts_max - dts_min)) + pos_min - approximate_keyframe_distance; |
1128 }else if(no_change==1){ | |
1129 // bisection, if interpolation failed to change min or max pos last time | |
1130 pos = (pos_min + pos_limit)>>1; | |
1131 }else{ | |
1132 // linear search if bisection failed, can only happen if there are very few or no keframes between min/max | |
1133 pos=pos_min; | |
310 | 1134 } |
355 | 1135 if(pos <= pos_min) |
1136 pos= pos_min + 1; | |
1137 else if(pos > pos_limit) | |
1138 pos= pos_limit; | |
1139 start_pos= pos; | |
1140 | |
1141 // read the next timestamp | |
1142 dts = mpegps_read_dts(s, stream_index, &pos, 1); | |
1143 if(pos == pos_max) | |
1144 no_change++; | |
1145 else | |
1146 no_change=0; | |
310 | 1147 #ifdef DEBUG_SEEK |
355 | 1148 printf("%Ld %Ld %Ld / %Ld %Ld %Ld target:%Ld limit:%Ld start:%Ld noc:%d\n", pos_min, pos, pos_max, dts_min, dts, dts_max, timestamp, pos_limit, start_pos, no_change); |
310 | 1149 #endif |
355 | 1150 assert(dts != AV_NOPTS_VALUE); |
1151 if (timestamp < dts) { | |
1152 pos_limit = start_pos - 1; | |
310 | 1153 pos_max = pos; |
355 | 1154 dts_max = dts; |
310 | 1155 } else { |
355 | 1156 pos_min = pos; |
1157 dts_min = dts; | |
1158 /* check if we are lucky */ | |
1159 if (timestamp == dts) | |
1160 break; | |
310 | 1161 } |
1162 } | |
355 | 1163 |
310 | 1164 pos = pos_min; |
1165 #ifdef DEBUG_SEEK | |
1166 pos_min = pos; | |
1167 dts_min = mpegps_read_dts(s, stream_index, &pos_min, 1); | |
1168 pos_min++; | |
1169 dts_max = mpegps_read_dts(s, stream_index, &pos_min, 1); | |
1170 printf("pos=0x%llx %0.3f<=%0.3f<=%0.3f\n", | |
1171 pos, dts_min / 90000.0, timestamp / 90000.0, dts_max / 90000.0); | |
1172 #endif | |
1173 /* do the seek */ | |
1174 url_fseek(&s->pb, pos, SEEK_SET); | |
1175 return 0; | |
1176 } | |
1177 | |
277
a313e1080322
disable encoders where appropriate (patch courtesy of BERO
melanson
parents:
276
diff
changeset
|
1178 #ifdef CONFIG_ENCODERS |
0 | 1179 static AVOutputFormat mpeg1system_mux = { |
1180 "mpeg", | |
1181 "MPEG1 System format", | |
14
b167760cd0aa
mimetype fixes patch by (Ryutaroh Matsumoto <ryutaroh at it dot ss dot titech dot ac dot jp>)
michaelni
parents:
0
diff
changeset
|
1182 "video/mpeg", |
0 | 1183 "mpg,mpeg", |
1184 sizeof(MpegMuxContext), | |
1185 CODEC_ID_MP2, | |
1186 CODEC_ID_MPEG1VIDEO, | |
1187 mpeg_mux_init, | |
1188 mpeg_mux_write_packet, | |
1189 mpeg_mux_end, | |
1190 }; | |
1191 | |
1192 static AVOutputFormat mpeg1vcd_mux = { | |
1193 "vcd", | |
1194 "MPEG1 System format (VCD)", | |
14
b167760cd0aa
mimetype fixes patch by (Ryutaroh Matsumoto <ryutaroh at it dot ss dot titech dot ac dot jp>)
michaelni
parents:
0
diff
changeset
|
1195 "video/mpeg", |
0 | 1196 NULL, |
1197 sizeof(MpegMuxContext), | |
1198 CODEC_ID_MP2, | |
1199 CODEC_ID_MPEG1VIDEO, | |
1200 mpeg_mux_init, | |
1201 mpeg_mux_write_packet, | |
1202 mpeg_mux_end, | |
1203 }; | |
1204 | |
1205 static AVOutputFormat mpeg2vob_mux = { | |
1206 "vob", | |
1207 "MPEG2 PS format (VOB)", | |
14
b167760cd0aa
mimetype fixes patch by (Ryutaroh Matsumoto <ryutaroh at it dot ss dot titech dot ac dot jp>)
michaelni
parents:
0
diff
changeset
|
1208 "video/mpeg", |
0 | 1209 "vob", |
1210 sizeof(MpegMuxContext), | |
1211 CODEC_ID_MP2, | |
335
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
1212 CODEC_ID_MPEG2VIDEO, |
0 | 1213 mpeg_mux_init, |
1214 mpeg_mux_write_packet, | |
1215 mpeg_mux_end, | |
1216 }; | |
277
a313e1080322
disable encoders where appropriate (patch courtesy of BERO
melanson
parents:
276
diff
changeset
|
1217 #endif //CONFIG_ENCODERS |
0 | 1218 |
190 | 1219 AVInputFormat mpegps_demux = { |
0 | 1220 "mpeg", |
1221 "MPEG PS format", | |
1222 sizeof(MpegDemuxContext), | |
1223 mpegps_probe, | |
1224 mpegps_read_header, | |
1225 mpegps_read_packet, | |
1226 mpegps_read_close, | |
310 | 1227 mpegps_read_seek, |
0 | 1228 }; |
1229 | |
1230 int mpegps_init(void) | |
1231 { | |
277
a313e1080322
disable encoders where appropriate (patch courtesy of BERO
melanson
parents:
276
diff
changeset
|
1232 #ifdef CONFIG_ENCODERS |
0 | 1233 av_register_output_format(&mpeg1system_mux); |
1234 av_register_output_format(&mpeg1vcd_mux); | |
1235 av_register_output_format(&mpeg2vob_mux); | |
277
a313e1080322
disable encoders where appropriate (patch courtesy of BERO
melanson
parents:
276
diff
changeset
|
1236 #endif //CONFIG_ENCODERS |
0 | 1237 av_register_input_format(&mpegps_demux); |
1238 return 0; | |
1239 } |