Mercurial > libavformat.hg
annotate mpeg.c @ 336:d75fd4c6ab62 libavformat
primitive LPCM generator
author | bellard |
---|---|
date | Tue, 16 Dec 2003 14:00:18 +0000 |
parents | b0ac206f232d |
children | f6b2b0718235 |
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 |
24 typedef struct { | |
65 | 25 uint8_t buffer[MAX_PAYLOAD_SIZE]; |
0 | 26 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
|
27 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
|
28 int frame_start_offset; /* starting offset of the frame + 1 (0 if none) */ |
65 | 29 uint8_t id; |
0 | 30 int max_buffer_size; /* in bytes */ |
31 int packet_number; | |
65 | 32 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
|
33 int64_t start_dts; |
336 | 34 uint8_t lpcm_header[3]; |
35 int lpcm_align; | |
0 | 36 } StreamInfo; |
37 | |
38 typedef struct { | |
39 int packet_size; /* required packet size */ | |
40 int packet_number; | |
41 int pack_header_freq; /* frequency (in packets^-1) at which we send pack headers */ | |
42 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
|
43 int system_header_size; |
0 | 44 int mux_rate; /* bitrate in units of 50 bytes/s */ |
45 /* stream info */ | |
46 int audio_bound; | |
47 int video_bound; | |
48 int is_mpeg2; | |
49 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
|
50 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
|
51 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
|
52 int64_t last_scr; /* current system clock */ |
0 | 53 } MpegMuxContext; |
54 | |
55 #define PACK_START_CODE ((unsigned int)0x000001ba) | |
56 #define SYSTEM_HEADER_START_CODE ((unsigned int)0x000001bb) | |
57 #define SEQUENCE_END_CODE ((unsigned int)0x000001b7) | |
58 #define PACKET_START_CODE_MASK ((unsigned int)0xffffff00) | |
59 #define PACKET_START_CODE_PREFIX ((unsigned int)0x00000100) | |
60 #define ISO_11172_END_CODE ((unsigned int)0x000001b9) | |
61 | |
62 /* mpeg2 */ | |
63 #define PROGRAM_STREAM_MAP 0x1bc | |
64 #define PRIVATE_STREAM_1 0x1bd | |
65 #define PADDING_STREAM 0x1be | |
66 #define PRIVATE_STREAM_2 0x1bf | |
67 | |
68 | |
69 #define AUDIO_ID 0xc0 | |
70 #define VIDEO_ID 0xe0 | |
336 | 71 #define AC3_ID 0x80 |
72 #define LPCM_ID 0xa0 | |
0 | 73 |
277
a313e1080322
disable encoders where appropriate (patch courtesy of BERO
melanson
parents:
276
diff
changeset
|
74 #ifdef CONFIG_ENCODERS |
0 | 75 extern AVOutputFormat mpeg1system_mux; |
76 extern AVOutputFormat mpeg1vcd_mux; | |
77 extern AVOutputFormat mpeg2vob_mux; | |
78 | |
336 | 79 static const int lpcm_freq_tab[4] = { 48000, 96000, 44100, 32000 }; |
80 | |
0 | 81 static int put_pack_header(AVFormatContext *ctx, |
65 | 82 uint8_t *buf, int64_t timestamp) |
0 | 83 { |
84 MpegMuxContext *s = ctx->priv_data; | |
85 PutBitContext pb; | |
86 | |
276 | 87 init_put_bits(&pb, buf, 128); |
0 | 88 |
89 put_bits(&pb, 32, PACK_START_CODE); | |
90 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
|
91 put_bits(&pb, 2, 0x1); |
0 | 92 } else { |
93 put_bits(&pb, 4, 0x2); | |
94 } | |
65 | 95 put_bits(&pb, 3, (uint32_t)((timestamp >> 30) & 0x07)); |
0 | 96 put_bits(&pb, 1, 1); |
65 | 97 put_bits(&pb, 15, (uint32_t)((timestamp >> 15) & 0x7fff)); |
0 | 98 put_bits(&pb, 1, 1); |
65 | 99 put_bits(&pb, 15, (uint32_t)((timestamp) & 0x7fff)); |
0 | 100 put_bits(&pb, 1, 1); |
101 if (s->is_mpeg2) { | |
102 /* clock extension */ | |
103 put_bits(&pb, 9, 0); | |
104 put_bits(&pb, 1, 1); | |
105 } | |
106 put_bits(&pb, 1, 1); | |
107 put_bits(&pb, 22, s->mux_rate); | |
108 put_bits(&pb, 1, 1); | |
109 if (s->is_mpeg2) { | |
110 put_bits(&pb, 5, 0x1f); /* reserved */ | |
111 put_bits(&pb, 3, 0); /* stuffing length */ | |
112 } | |
113 flush_put_bits(&pb); | |
114 return pbBufPtr(&pb) - pb.buf; | |
115 } | |
116 | |
65 | 117 static int put_system_header(AVFormatContext *ctx, uint8_t *buf) |
0 | 118 { |
119 MpegMuxContext *s = ctx->priv_data; | |
120 int size, rate_bound, i, private_stream_coded, id; | |
121 PutBitContext pb; | |
122 | |
276 | 123 init_put_bits(&pb, buf, 128); |
0 | 124 |
125 put_bits(&pb, 32, SYSTEM_HEADER_START_CODE); | |
126 put_bits(&pb, 16, 0); | |
127 put_bits(&pb, 1, 1); | |
128 | |
129 rate_bound = s->mux_rate; /* maximum bit rate of the multiplexed stream */ | |
130 put_bits(&pb, 22, rate_bound); | |
131 put_bits(&pb, 1, 1); /* marker */ | |
132 put_bits(&pb, 6, s->audio_bound); | |
133 | |
134 put_bits(&pb, 1, 1); /* variable bitrate */ | |
135 put_bits(&pb, 1, 1); /* non constrainted bit stream */ | |
136 | |
137 put_bits(&pb, 1, 0); /* audio locked */ | |
138 put_bits(&pb, 1, 0); /* video locked */ | |
139 put_bits(&pb, 1, 1); /* marker */ | |
140 | |
141 put_bits(&pb, 5, s->video_bound); | |
142 put_bits(&pb, 8, 0xff); /* reserved byte */ | |
143 | |
144 /* audio stream info */ | |
145 private_stream_coded = 0; | |
146 for(i=0;i<ctx->nb_streams;i++) { | |
147 StreamInfo *stream = ctx->streams[i]->priv_data; | |
148 id = stream->id; | |
149 if (id < 0xc0) { | |
150 /* special case for private streams (AC3 use that) */ | |
151 if (private_stream_coded) | |
152 continue; | |
153 private_stream_coded = 1; | |
154 id = 0xbd; | |
155 } | |
156 put_bits(&pb, 8, id); /* stream ID */ | |
157 put_bits(&pb, 2, 3); | |
158 if (id < 0xe0) { | |
159 /* audio */ | |
160 put_bits(&pb, 1, 0); | |
161 put_bits(&pb, 13, stream->max_buffer_size / 128); | |
162 } else { | |
163 /* video */ | |
164 put_bits(&pb, 1, 1); | |
165 put_bits(&pb, 13, stream->max_buffer_size / 1024); | |
166 } | |
167 } | |
168 flush_put_bits(&pb); | |
169 size = pbBufPtr(&pb) - pb.buf; | |
170 /* patch packet size */ | |
171 buf[4] = (size - 6) >> 8; | |
172 buf[5] = (size - 6) & 0xff; | |
173 | |
174 return size; | |
175 } | |
176 | |
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
|
177 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
|
178 { |
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
|
179 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
|
180 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
|
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 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
|
183 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
|
184 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
|
185 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
|
186 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
|
187 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
|
188 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
|
189 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
|
190 } |
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 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
|
192 } |
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 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
|
194 } |
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 |
0 | 196 static int mpeg_mux_init(AVFormatContext *ctx) |
197 { | |
198 MpegMuxContext *s = ctx->priv_data; | |
336 | 199 int bitrate, i, mpa_id, mpv_id, ac3_id, lpcm_id, j; |
0 | 200 AVStream *st; |
201 StreamInfo *stream; | |
202 | |
203 s->packet_number = 0; | |
204 s->is_vcd = (ctx->oformat == &mpeg1vcd_mux); | |
205 s->is_mpeg2 = (ctx->oformat == &mpeg2vob_mux); | |
206 | |
207 if (s->is_vcd) | |
208 s->packet_size = 2324; /* VCD packet size */ | |
209 else | |
210 s->packet_size = 2048; | |
211 | |
212 s->audio_bound = 0; | |
213 s->video_bound = 0; | |
214 mpa_id = AUDIO_ID; | |
336 | 215 ac3_id = AC3_ID; |
0 | 216 mpv_id = VIDEO_ID; |
336 | 217 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
|
218 s->scr_stream_index = -1; |
0 | 219 for(i=0;i<ctx->nb_streams;i++) { |
220 st = ctx->streams[i]; | |
221 stream = av_mallocz(sizeof(StreamInfo)); | |
222 if (!stream) | |
223 goto fail; | |
224 st->priv_data = stream; | |
225 | |
226 switch(st->codec.codec_type) { | |
227 case CODEC_TYPE_AUDIO: | |
336 | 228 if (st->codec.codec_id == CODEC_ID_AC3) { |
0 | 229 stream->id = ac3_id++; |
336 | 230 } else if (st->codec.codec_id == CODEC_ID_PCM_S16BE) { |
231 stream->id = lpcm_id++; | |
232 for(j = 0; j < 4; j++) { | |
233 if (lpcm_freq_tab[j] == st->codec.sample_rate) | |
234 break; | |
235 } | |
236 if (j == 4) | |
237 goto fail; | |
238 if (st->codec.channels > 8) | |
239 return -1; | |
240 stream->lpcm_header[0] = 0x0c; | |
241 stream->lpcm_header[1] = (st->codec.channels - 1) | (j << 4); | |
242 stream->lpcm_header[2] = 0x80; | |
243 stream->lpcm_align = st->codec.channels * 2; | |
244 } else { | |
0 | 245 stream->id = mpa_id++; |
336 | 246 } |
0 | 247 stream->max_buffer_size = 4 * 1024; |
248 s->audio_bound++; | |
249 break; | |
250 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
|
251 /* 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
|
252 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
|
253 s->scr_stream_index = i; |
0 | 254 stream->id = mpv_id++; |
255 stream->max_buffer_size = 46 * 1024; | |
256 s->video_bound++; | |
257 break; | |
258 default: | |
259 av_abort(); | |
260 } | |
261 } | |
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
|
262 /* 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
|
263 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
|
264 s->scr_stream_index = 0; |
0 | 265 |
266 /* we increase slightly the bitrate to take into account the | |
267 headers. XXX: compute it exactly */ | |
268 bitrate = 2000; | |
269 for(i=0;i<ctx->nb_streams;i++) { | |
270 st = ctx->streams[i]; | |
271 bitrate += st->codec.bit_rate; | |
272 } | |
273 s->mux_rate = (bitrate + (8 * 50) - 1) / (8 * 50); | |
274 | |
275 if (s->is_vcd || s->is_mpeg2) | |
276 /* every packet */ | |
277 s->pack_header_freq = 1; | |
278 else | |
279 /* every 2 seconds */ | |
280 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
|
281 |
b19f70a6d60f
1/0 fix by (Tim Allen <tim at proximity dot com dot au>)
michael
parents:
277
diff
changeset
|
282 /* 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
|
283 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
|
284 s->pack_header_freq = 1; |
0 | 285 |
286 if (s->is_mpeg2) | |
287 /* every 200 packets. Need to look at the spec. */ | |
288 s->system_header_freq = s->pack_header_freq * 40; | |
289 else if (s->is_vcd) | |
290 /* every 40 packets, this is my invention */ | |
291 s->system_header_freq = s->pack_header_freq * 40; | |
292 else | |
293 s->system_header_freq = s->pack_header_freq * 5; | |
294 | |
295 for(i=0;i<ctx->nb_streams;i++) { | |
296 stream = ctx->streams[i]->priv_data; | |
297 stream->buffer_ptr = 0; | |
298 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
|
299 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
|
300 stream->start_dts = AV_NOPTS_VALUE; |
0 | 301 } |
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
|
302 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
|
303 s->last_scr = 0; |
0 | 304 return 0; |
305 fail: | |
306 for(i=0;i<ctx->nb_streams;i++) { | |
307 av_free(ctx->streams[i]->priv_data); | |
308 } | |
309 return -ENOMEM; | |
310 } | |
311 | |
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
|
312 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
|
313 { |
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
|
314 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
|
315 (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
|
316 (((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
|
317 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
|
318 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
|
319 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
|
320 } |
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 |
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
|
322 |
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
|
323 /* 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
|
324 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
|
325 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
|
326 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
|
327 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
|
328 { |
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 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
|
330 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
|
331 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
|
332 |
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 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
|
334 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
|
335 /* 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
|
336 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
|
337 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
|
338 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
|
339 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
|
340 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
|
341 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
|
342 } |
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 |
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 /* 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
|
345 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
|
346 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
|
347 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
|
348 if (pts != AV_NOPTS_VALUE) { |
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 (dts != AV_NOPTS_VALUE) |
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 += 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
|
351 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
|
352 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
|
353 } 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
|
354 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
|
355 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
|
356 } |
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 |
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 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
|
359 if (stream->id < 0xc0) { |
336 | 360 /* 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
|
361 buf_index += 4; |
336 | 362 if (stream->id >= 0xa0) { |
363 int n; | |
364 buf_index += 3; | |
365 /* NOTE: we round the payload size to an integer number of | |
366 LPCM samples */ | |
367 n = (s->packet_size - buf_index) % stream->lpcm_align; | |
368 if (n) | |
369 buf_index += (stream->lpcm_align - n); | |
370 } | |
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
|
371 } |
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
|
372 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
|
373 } |
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 |
0 | 375 /* 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
|
376 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
|
377 int64_t pts, int64_t dts, int64_t scr) |
0 | 378 { |
379 MpegMuxContext *s = ctx->priv_data; | |
380 StreamInfo *stream = ctx->streams[stream_index]->priv_data; | |
65 | 381 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
|
382 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
|
383 int packet_size; |
65 | 384 uint8_t buffer[128]; |
0 | 385 |
386 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
|
387 |
0 | 388 #if 0 |
389 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
|
390 id, pts / 90000.0); |
0 | 391 #endif |
392 | |
393 buf_ptr = buffer; | |
394 if (((s->packet_number % s->pack_header_freq) == 0)) { | |
395 /* 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
|
396 size = put_pack_header(ctx, buf_ptr, scr); |
0 | 397 buf_ptr += size; |
398 if ((s->packet_number % s->system_header_freq) == 0) { | |
399 size = put_system_header(ctx, buf_ptr); | |
400 buf_ptr += size; | |
401 } | |
402 } | |
403 size = buf_ptr - buffer; | |
404 put_buffer(&ctx->pb, buffer, size); | |
405 | |
406 /* packet header */ | |
407 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
|
408 header_len = 3; |
0 | 409 } 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
|
410 header_len = 0; |
0 | 411 } |
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
|
412 if (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
|
413 if (dts != 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
|
414 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
|
415 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
|
416 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
|
417 } 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
|
418 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
|
419 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
|
420 } |
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 |
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
|
422 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
|
423 payload_size = packet_size - header_len; |
0 | 424 if (id < 0xc0) { |
425 startcode = PRIVATE_STREAM_1; | |
426 payload_size -= 4; | |
336 | 427 if (id >= 0xa0) |
428 payload_size -= 3; | |
0 | 429 } else { |
430 startcode = 0x100 + id; | |
431 } | |
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
|
432 |
0 | 433 stuffing_size = payload_size - stream->buffer_ptr; |
434 if (stuffing_size < 0) | |
435 stuffing_size = 0; | |
436 put_be32(&ctx->pb, startcode); | |
437 | |
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
|
438 put_be16(&ctx->pb, packet_size); |
0 | 439 /* stuffing */ |
440 for(i=0;i<stuffing_size;i++) | |
441 put_byte(&ctx->pb, 0xff); | |
442 | |
443 if (s->is_mpeg2) { | |
444 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
|
445 |
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
|
446 if (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
|
447 if (dts != 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
|
448 put_byte(&ctx->pb, 0xc0); /* flags */ |
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 put_byte(&ctx->pb, header_len - 3); |
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 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
|
451 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
|
452 } 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
|
453 put_byte(&ctx->pb, 0x80); /* flags */ |
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_byte(&ctx->pb, header_len - 3); |
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, 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
|
456 } |
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 } 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
|
458 put_byte(&ctx->pb, 0x00); /* flags */ |
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_byte(&ctx->pb, header_len - 3); |
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 if (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
|
463 if (dts != 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
|
464 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
|
465 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
|
466 } 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
|
467 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
|
468 } |
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 } 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
|
470 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
|
471 } |
0 | 472 } |
473 | |
474 if (startcode == PRIVATE_STREAM_1) { | |
475 put_byte(&ctx->pb, id); | |
336 | 476 if (id >= 0xa0) { |
477 /* LPCM (XXX: check nb_frames) */ | |
478 put_byte(&ctx->pb, 7); | |
479 put_be16(&ctx->pb, 4); /* skip 3 header bytes */ | |
480 put_byte(&ctx->pb, stream->lpcm_header[0]); | |
481 put_byte(&ctx->pb, stream->lpcm_header[1]); | |
482 put_byte(&ctx->pb, stream->lpcm_header[2]); | |
483 } else { | |
484 /* 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
|
485 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
|
486 put_be16(&ctx->pb, stream->frame_start_offset); |
0 | 487 } |
488 } | |
489 | |
490 /* output data */ | |
491 put_buffer(&ctx->pb, stream->buffer, payload_size - stuffing_size); | |
492 put_flush_packet(&ctx->pb); | |
493 | |
494 s->packet_number++; | |
495 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
|
496 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
|
497 stream->frame_start_offset = 0; |
0 | 498 } |
499 | |
500 static int mpeg_mux_write_packet(AVFormatContext *ctx, int stream_index, | |
241 | 501 const uint8_t *buf, int size, int64_t pts) |
0 | 502 { |
503 MpegMuxContext *s = ctx->priv_data; | |
504 AVStream *st = ctx->streams[stream_index]; | |
505 StreamInfo *stream = st->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
|
506 int64_t dts, new_start_pts, 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
|
507 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
|
508 |
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
|
509 /* 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
|
510 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
|
511 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
|
512 s->last_scr = pts; |
0 | 513 |
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
|
514 #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
|
515 printf("%d: pts=%0.3f scr=%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
|
516 stream_index, pts / 90000.0, s->last_scr / 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
|
517 #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
|
518 |
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
|
519 /* XXX: currently no way to pass dts, will change soon */ |
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
|
520 dts = 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
|
521 |
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
|
522 /* 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
|
523 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
|
524 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
|
525 |
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
|
526 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
|
527 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
|
528 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
|
529 } |
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
|
530 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
|
531 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
|
532 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
|
533 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
|
534 /* 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
|
535 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
|
536 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
|
537 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
|
538 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
|
539 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
|
540 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
|
541 } |
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
|
542 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
|
543 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
|
544 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
|
545 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
|
546 stream->frame_start_offset = stream->buffer_ptr; |
0 | 547 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
|
548 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
|
549 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
|
550 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
|
551 len = avail_size - stream->buffer_ptr; |
0 | 552 if (len > size) |
553 len = size; | |
554 memcpy(stream->buffer + stream->buffer_ptr, buf, len); | |
555 stream->buffer_ptr += len; | |
556 buf += len; | |
557 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
|
558 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
|
559 /* 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
|
560 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
|
561 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
|
562 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
|
563 /* 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
|
564 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
|
565 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
|
566 stream->start_dts = AV_NOPTS_VALUE; |
0 | 567 } |
568 } | |
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
|
569 |
0 | 570 return 0; |
571 } | |
572 | |
573 static int mpeg_mux_end(AVFormatContext *ctx) | |
574 { | |
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 MpegMuxContext *s = ctx->priv_data; |
0 | 576 StreamInfo *stream; |
577 int i; | |
578 | |
579 /* flush each packet */ | |
580 for(i=0;i<ctx->nb_streams;i++) { | |
581 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
|
582 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
|
583 /* 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
|
584 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
|
585 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
|
586 s->last_scr); |
0 | 587 } |
588 } | |
589 | |
242 | 590 /* End header according to MPEG1 systems standard. We do not write |
591 it as it is usually not needed by decoders and because it | |
592 complicates MPEG stream concatenation. */ | |
0 | 593 //put_be32(&ctx->pb, ISO_11172_END_CODE); |
594 //put_flush_packet(&ctx->pb); | |
237
35231c0be8e5
memleak fix by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michaelni
parents:
210
diff
changeset
|
595 |
35231c0be8e5
memleak fix by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michaelni
parents:
210
diff
changeset
|
596 for(i=0;i<ctx->nb_streams;i++) |
35231c0be8e5
memleak fix by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michaelni
parents:
210
diff
changeset
|
597 av_freep(&ctx->streams[i]->priv_data); |
35231c0be8e5
memleak fix by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michaelni
parents:
210
diff
changeset
|
598 |
0 | 599 return 0; |
600 } | |
277
a313e1080322
disable encoders where appropriate (patch courtesy of BERO
melanson
parents:
276
diff
changeset
|
601 #endif //CONFIG_ENCODERS |
0 | 602 |
603 /*********************************************/ | |
604 /* demux code */ | |
605 | |
606 #define MAX_SYNC_SIZE 100000 | |
607 | |
608 static int mpegps_probe(AVProbeData *p) | |
609 { | |
165
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
610 int code, c, i; |
0 | 611 |
165
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
612 code = 0xff; |
0 | 613 /* we search the first start code. If it is a packet start code, |
614 then we decide it is mpeg ps. We do not send highest value to | |
615 give a chance to mpegts */ | |
49 | 616 /* NOTE: the search range was restricted to avoid too many false |
617 detections */ | |
618 | |
619 if (p->buf_size < 6) | |
620 return 0; | |
165
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
621 |
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
622 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
|
623 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
|
624 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
|
625 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
|
626 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
|
627 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
|
628 (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
|
629 (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
|
630 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
|
631 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
|
632 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
|
633 code == PADDING_STREAM) |
210 | 634 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
|
635 else |
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
636 return 0; |
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
637 } |
0 | 638 } |
639 return 0; | |
640 } | |
641 | |
642 | |
643 typedef struct MpegDemuxContext { | |
644 int header_state; | |
645 } MpegDemuxContext; | |
646 | |
310 | 647 static int mpegps_read_header(AVFormatContext *s, |
648 AVFormatParameters *ap) | |
649 { | |
650 MpegDemuxContext *m = s->priv_data; | |
651 m->header_state = 0xff; | |
652 s->ctx_flags |= AVFMTCTX_NOHEADER; | |
653 | |
654 /* no need to do more */ | |
655 return 0; | |
656 } | |
657 | |
658 static int64_t get_pts(ByteIOContext *pb, int c) | |
659 { | |
660 int64_t pts; | |
661 int val; | |
662 | |
663 if (c < 0) | |
664 c = get_byte(pb); | |
665 pts = (int64_t)((c >> 1) & 0x07) << 30; | |
666 val = get_be16(pb); | |
667 pts |= (int64_t)(val >> 1) << 15; | |
668 val = get_be16(pb); | |
669 pts |= (int64_t)(val >> 1); | |
670 return pts; | |
671 } | |
672 | |
673 static int find_next_start_code(ByteIOContext *pb, int *size_ptr, | |
674 uint32_t *header_state) | |
0 | 675 { |
676 unsigned int state, v; | |
677 int val, n; | |
678 | |
679 state = *header_state; | |
680 n = *size_ptr; | |
681 while (n > 0) { | |
682 if (url_feof(pb)) | |
683 break; | |
684 v = get_byte(pb); | |
685 n--; | |
686 if (state == 0x000001) { | |
687 state = ((state << 8) | v) & 0xffffff; | |
688 val = state; | |
689 goto found; | |
690 } | |
691 state = ((state << 8) | v) & 0xffffff; | |
692 } | |
693 val = -1; | |
694 found: | |
695 *header_state = state; | |
696 *size_ptr = n; | |
697 return val; | |
698 } | |
699 | |
310 | 700 /* XXX: optimize */ |
701 static int find_prev_start_code(ByteIOContext *pb, int *size_ptr) | |
0 | 702 { |
310 | 703 int64_t pos, pos_start; |
704 int max_size, start_code; | |
705 | |
706 max_size = *size_ptr; | |
707 pos_start = url_ftell(pb); | |
708 | |
709 /* in order to go faster, we fill the buffer */ | |
710 pos = pos_start - 16386; | |
711 if (pos < 0) | |
712 pos = 0; | |
713 url_fseek(pb, pos, SEEK_SET); | |
714 get_byte(pb); | |
293
62cec412a186
make AVFMT_NOHEADER flag dynamic - added av_open_input_stream()
bellard
parents:
291
diff
changeset
|
715 |
310 | 716 pos = pos_start; |
717 for(;;) { | |
718 pos--; | |
719 if (pos < 0 || (pos_start - pos) >= max_size) { | |
720 start_code = -1; | |
721 goto the_end; | |
722 } | |
723 url_fseek(pb, pos, SEEK_SET); | |
724 start_code = get_be32(pb); | |
725 if ((start_code & 0xffffff00) == 0x100) | |
726 break; | |
727 } | |
728 the_end: | |
729 *size_ptr = pos_start - pos; | |
730 return start_code; | |
0 | 731 } |
732 | |
310 | 733 /* read the next (or previous) PES header. Return its position in ppos |
734 (if not NULL), and its start code, pts and dts. | |
735 */ | |
736 static int mpegps_read_pes_header(AVFormatContext *s, | |
737 int64_t *ppos, int *pstart_code, | |
738 int64_t *ppts, int64_t *pdts, int find_next) | |
0 | 739 { |
740 MpegDemuxContext *m = s->priv_data; | |
310 | 741 int len, size, startcode, c, flags, header_len; |
742 int64_t pts, dts, last_pos; | |
0 | 743 |
310 | 744 last_pos = -1; |
0 | 745 redo: |
310 | 746 if (find_next) { |
747 /* next start code (should be immediately after) */ | |
748 m->header_state = 0xff; | |
749 size = MAX_SYNC_SIZE; | |
750 startcode = find_next_start_code(&s->pb, &size, &m->header_state); | |
751 } else { | |
752 if (last_pos >= 0) | |
753 url_fseek(&s->pb, last_pos, SEEK_SET); | |
754 size = MAX_SYNC_SIZE; | |
755 startcode = find_prev_start_code(&s->pb, &size); | |
756 last_pos = url_ftell(&s->pb) - 4; | |
757 } | |
0 | 758 //printf("startcode=%x pos=0x%Lx\n", startcode, url_ftell(&s->pb)); |
759 if (startcode < 0) | |
760 return -EIO; | |
761 if (startcode == PACK_START_CODE) | |
762 goto redo; | |
763 if (startcode == SYSTEM_HEADER_START_CODE) | |
764 goto redo; | |
765 if (startcode == PADDING_STREAM || | |
766 startcode == PRIVATE_STREAM_2) { | |
767 /* skip them */ | |
768 len = get_be16(&s->pb); | |
769 url_fskip(&s->pb, len); | |
770 goto redo; | |
771 } | |
772 /* find matching stream */ | |
773 if (!((startcode >= 0x1c0 && startcode <= 0x1df) || | |
774 (startcode >= 0x1e0 && startcode <= 0x1ef) || | |
775 (startcode == 0x1bd))) | |
776 goto redo; | |
310 | 777 if (ppos) { |
778 *ppos = url_ftell(&s->pb) - 4; | |
779 } | |
0 | 780 len = get_be16(&s->pb); |
781 pts = AV_NOPTS_VALUE; | |
782 dts = AV_NOPTS_VALUE; | |
783 /* stuffing */ | |
784 for(;;) { | |
310 | 785 if (len < 1) |
786 goto redo; | |
0 | 787 c = get_byte(&s->pb); |
788 len--; | |
789 /* XXX: for mpeg1, should test only bit 7 */ | |
790 if (c != 0xff) | |
791 break; | |
792 } | |
793 if ((c & 0xc0) == 0x40) { | |
794 /* buffer scale & size */ | |
310 | 795 if (len < 2) |
796 goto redo; | |
0 | 797 get_byte(&s->pb); |
798 c = get_byte(&s->pb); | |
799 len -= 2; | |
800 } | |
801 if ((c & 0xf0) == 0x20) { | |
310 | 802 if (len < 4) |
803 goto redo; | |
804 dts = pts = get_pts(&s->pb, c); | |
0 | 805 len -= 4; |
806 } else if ((c & 0xf0) == 0x30) { | |
310 | 807 if (len < 9) |
808 goto redo; | |
0 | 809 pts = get_pts(&s->pb, c); |
810 dts = get_pts(&s->pb, -1); | |
811 len -= 9; | |
812 } else if ((c & 0xc0) == 0x80) { | |
813 /* mpeg 2 PES */ | |
814 if ((c & 0x30) != 0) { | |
310 | 815 /* Encrypted multiplex not handled */ |
816 goto redo; | |
0 | 817 } |
818 flags = get_byte(&s->pb); | |
819 header_len = get_byte(&s->pb); | |
820 len -= 2; | |
821 if (header_len > len) | |
822 goto redo; | |
823 if ((flags & 0xc0) == 0x80) { | |
310 | 824 dts = pts = get_pts(&s->pb, -1); |
825 if (header_len < 5) | |
826 goto redo; | |
0 | 827 header_len -= 5; |
828 len -= 5; | |
829 } if ((flags & 0xc0) == 0xc0) { | |
830 pts = get_pts(&s->pb, -1); | |
831 dts = get_pts(&s->pb, -1); | |
310 | 832 if (header_len < 10) |
833 goto redo; | |
0 | 834 header_len -= 10; |
835 len -= 10; | |
836 } | |
837 len -= header_len; | |
838 while (header_len > 0) { | |
839 get_byte(&s->pb); | |
840 header_len--; | |
841 } | |
842 } | |
843 if (startcode == 0x1bd) { | |
310 | 844 if (len < 1) |
845 goto redo; | |
0 | 846 startcode = get_byte(&s->pb); |
847 len--; | |
848 if (startcode >= 0x80 && startcode <= 0xbf) { | |
849 /* audio: skip header */ | |
310 | 850 if (len < 3) |
851 goto redo; | |
0 | 852 get_byte(&s->pb); |
853 get_byte(&s->pb); | |
854 get_byte(&s->pb); | |
855 len -= 3; | |
856 } | |
857 } | |
310 | 858 *pstart_code = startcode; |
859 *ppts = pts; | |
860 *pdts = dts; | |
861 return len; | |
862 } | |
863 | |
864 static int mpegps_read_packet(AVFormatContext *s, | |
865 AVPacket *pkt) | |
866 { | |
867 AVStream *st; | |
868 int len, startcode, i, type, codec_id; | |
869 int64_t pts, dts; | |
870 | |
871 redo: | |
872 len = mpegps_read_pes_header(s, NULL, &startcode, &pts, &dts, 1); | |
873 if (len < 0) | |
874 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
|
875 |
0 | 876 /* now find stream */ |
877 for(i=0;i<s->nb_streams;i++) { | |
878 st = s->streams[i]; | |
879 if (st->id == startcode) | |
880 goto found; | |
881 } | |
882 if (startcode >= 0x1e0 && startcode <= 0x1ef) { | |
883 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
|
884 codec_id = CODEC_ID_MPEG2VIDEO; |
0 | 885 } else if (startcode >= 0x1c0 && startcode <= 0x1df) { |
886 type = CODEC_TYPE_AUDIO; | |
887 codec_id = CODEC_ID_MP2; | |
888 } else if (startcode >= 0x80 && startcode <= 0x9f) { | |
889 type = CODEC_TYPE_AUDIO; | |
890 codec_id = CODEC_ID_AC3; | |
41 | 891 } else if (startcode >= 0xa0 && startcode <= 0xbf) { |
892 type = CODEC_TYPE_AUDIO; | |
893 codec_id = CODEC_ID_PCM_S16BE; | |
0 | 894 } else { |
895 skip: | |
896 /* skip packet */ | |
897 url_fskip(&s->pb, len); | |
898 goto redo; | |
899 } | |
900 /* no stream found: add a new stream */ | |
901 st = av_new_stream(s, startcode); | |
902 if (!st) | |
903 goto skip; | |
904 st->codec.codec_type = type; | |
905 st->codec.codec_id = codec_id; | |
310 | 906 if (codec_id != CODEC_ID_PCM_S16BE) |
907 st->need_parsing = 1; | |
0 | 908 found: |
41 | 909 if (startcode >= 0xa0 && startcode <= 0xbf) { |
910 int b1, freq; | |
911 | |
912 /* for LPCM, we just skip the header and consider it is raw | |
913 audio data */ | |
914 if (len <= 3) | |
915 goto skip; | |
916 get_byte(&s->pb); /* emphasis (1), muse(1), reserved(1), frame number(5) */ | |
917 b1 = get_byte(&s->pb); /* quant (2), freq(2), reserved(1), channels(3) */ | |
918 get_byte(&s->pb); /* dynamic range control (0x80 = off) */ | |
919 len -= 3; | |
920 freq = (b1 >> 4) & 3; | |
921 st->codec.sample_rate = lpcm_freq_tab[freq]; | |
922 st->codec.channels = 1 + (b1 & 7); | |
923 st->codec.bit_rate = st->codec.channels * st->codec.sample_rate * 2; | |
924 } | |
0 | 925 av_new_packet(pkt, len); |
926 get_buffer(&s->pb, pkt->data, pkt->size); | |
927 pkt->pts = pts; | |
310 | 928 pkt->dts = dts; |
0 | 929 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
|
930 #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
|
931 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
|
932 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
|
933 #endif |
0 | 934 return 0; |
935 } | |
936 | |
937 static int mpegps_read_close(AVFormatContext *s) | |
938 { | |
939 return 0; | |
940 } | |
941 | |
310 | 942 static int64_t mpegps_read_dts(AVFormatContext *s, int stream_index, |
943 int64_t *ppos, int find_next) | |
944 { | |
945 int len, startcode; | |
946 int64_t pos, pts, dts; | |
947 | |
948 pos = *ppos; | |
949 #ifdef DEBUG_SEEK | |
950 printf("read_dts: pos=0x%llx next=%d -> ", pos, find_next); | |
951 #endif | |
952 url_fseek(&s->pb, pos, SEEK_SET); | |
953 for(;;) { | |
954 len = mpegps_read_pes_header(s, &pos, &startcode, &pts, &dts, find_next); | |
955 if (len < 0) { | |
956 #ifdef DEBUG_SEEK | |
957 printf("none (ret=%d)\n", len); | |
958 #endif | |
959 return AV_NOPTS_VALUE; | |
960 } | |
961 if (startcode == s->streams[stream_index]->id && | |
962 dts != AV_NOPTS_VALUE) { | |
963 break; | |
964 } | |
965 if (find_next) { | |
966 url_fskip(&s->pb, len); | |
967 } else { | |
968 url_fseek(&s->pb, pos, SEEK_SET); | |
969 } | |
970 } | |
971 #ifdef DEBUG_SEEK | |
972 printf("pos=0x%llx dts=0x%llx %0.3f\n", pos, dts, dts / 90000.0); | |
973 #endif | |
974 *ppos = pos; | |
975 return dts; | |
976 } | |
977 | |
978 static int find_stream_index(AVFormatContext *s) | |
979 { | |
980 int i; | |
981 AVStream *st; | |
982 | |
983 if (s->nb_streams <= 0) | |
984 return -1; | |
985 for(i = 0; i < s->nb_streams; i++) { | |
986 st = s->streams[i]; | |
987 if (st->codec.codec_type == CODEC_TYPE_VIDEO) { | |
988 return i; | |
989 } | |
990 } | |
991 return 0; | |
992 } | |
993 | |
994 static int mpegps_read_seek(AVFormatContext *s, | |
995 int stream_index, int64_t timestamp) | |
996 { | |
997 int64_t pos_min, pos_max, pos; | |
998 int64_t dts_min, dts_max, dts; | |
999 | |
1000 timestamp = (timestamp * 90000) / AV_TIME_BASE; | |
1001 | |
1002 #ifdef DEBUG_SEEK | |
1003 printf("read_seek: %d %0.3f\n", stream_index, timestamp / 90000.0); | |
1004 #endif | |
1005 | |
1006 /* XXX: find stream_index by looking at the first PES packet found */ | |
1007 if (stream_index < 0) { | |
1008 stream_index = find_stream_index(s); | |
1009 if (stream_index < 0) | |
1010 return -1; | |
1011 } | |
1012 pos_min = 0; | |
1013 dts_min = mpegps_read_dts(s, stream_index, &pos_min, 1); | |
1014 if (dts_min == AV_NOPTS_VALUE) { | |
1015 /* we can reach this case only if no PTS are present in | |
1016 the whole stream */ | |
1017 return -1; | |
1018 } | |
1019 pos_max = url_filesize(url_fileno(&s->pb)) - 1; | |
1020 dts_max = mpegps_read_dts(s, stream_index, &pos_max, 0); | |
1021 | |
1022 while (pos_min <= pos_max) { | |
1023 #ifdef DEBUG_SEEK | |
1024 printf("pos_min=0x%llx pos_max=0x%llx dts_min=%0.3f dts_max=%0.3f\n", | |
1025 pos_min, pos_max, | |
1026 dts_min / 90000.0, dts_max / 90000.0); | |
1027 #endif | |
1028 if (timestamp <= dts_min) { | |
1029 pos = pos_min; | |
1030 goto found; | |
1031 } else if (timestamp >= dts_max) { | |
1032 pos = pos_max; | |
1033 goto found; | |
1034 } else { | |
1035 /* interpolate position (better than dichotomy) */ | |
1036 pos = (int64_t)((double)(pos_max - pos_min) * | |
1037 (double)(timestamp - dts_min) / | |
1038 (double)(dts_max - dts_min)) + pos_min; | |
1039 } | |
1040 #ifdef DEBUG_SEEK | |
1041 printf("pos=0x%llx\n", pos); | |
1042 #endif | |
1043 /* read the next timestamp */ | |
1044 dts = mpegps_read_dts(s, stream_index, &pos, 1); | |
1045 /* check if we are lucky */ | |
1046 if (dts == AV_NOPTS_VALUE) { | |
1047 /* should never happen */ | |
1048 pos = pos_min; | |
1049 goto found; | |
1050 } else if (timestamp == dts) { | |
1051 goto found; | |
1052 } else if (timestamp < dts) { | |
1053 pos_max = pos; | |
1054 dts_max = mpegps_read_dts(s, stream_index, &pos_max, 0); | |
1055 if (dts_max == AV_NOPTS_VALUE) { | |
1056 /* should never happen */ | |
1057 break; | |
1058 } else if (timestamp >= dts_max) { | |
1059 pos = pos_max; | |
1060 goto found; | |
1061 } | |
1062 } else { | |
1063 pos_min = pos + 1; | |
1064 dts_min = mpegps_read_dts(s, stream_index, &pos_min, 1); | |
1065 if (dts_min == AV_NOPTS_VALUE) { | |
1066 /* should never happen */ | |
1067 goto found; | |
1068 } else if (timestamp <= dts_min) { | |
1069 goto found; | |
1070 } | |
1071 } | |
1072 } | |
1073 pos = pos_min; | |
1074 found: | |
1075 #ifdef DEBUG_SEEK | |
1076 pos_min = pos; | |
1077 dts_min = mpegps_read_dts(s, stream_index, &pos_min, 1); | |
1078 pos_min++; | |
1079 dts_max = mpegps_read_dts(s, stream_index, &pos_min, 1); | |
1080 printf("pos=0x%llx %0.3f<=%0.3f<=%0.3f\n", | |
1081 pos, dts_min / 90000.0, timestamp / 90000.0, dts_max / 90000.0); | |
1082 #endif | |
1083 /* do the seek */ | |
1084 url_fseek(&s->pb, pos, SEEK_SET); | |
1085 return 0; | |
1086 } | |
1087 | |
277
a313e1080322
disable encoders where appropriate (patch courtesy of BERO
melanson
parents:
276
diff
changeset
|
1088 #ifdef CONFIG_ENCODERS |
0 | 1089 static AVOutputFormat mpeg1system_mux = { |
1090 "mpeg", | |
1091 "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
|
1092 "video/mpeg", |
0 | 1093 "mpg,mpeg", |
1094 sizeof(MpegMuxContext), | |
1095 CODEC_ID_MP2, | |
1096 CODEC_ID_MPEG1VIDEO, | |
1097 mpeg_mux_init, | |
1098 mpeg_mux_write_packet, | |
1099 mpeg_mux_end, | |
1100 }; | |
1101 | |
1102 static AVOutputFormat mpeg1vcd_mux = { | |
1103 "vcd", | |
1104 "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
|
1105 "video/mpeg", |
0 | 1106 NULL, |
1107 sizeof(MpegMuxContext), | |
1108 CODEC_ID_MP2, | |
1109 CODEC_ID_MPEG1VIDEO, | |
1110 mpeg_mux_init, | |
1111 mpeg_mux_write_packet, | |
1112 mpeg_mux_end, | |
1113 }; | |
1114 | |
1115 static AVOutputFormat mpeg2vob_mux = { | |
1116 "vob", | |
1117 "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
|
1118 "video/mpeg", |
0 | 1119 "vob", |
1120 sizeof(MpegMuxContext), | |
1121 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
|
1122 CODEC_ID_MPEG2VIDEO, |
0 | 1123 mpeg_mux_init, |
1124 mpeg_mux_write_packet, | |
1125 mpeg_mux_end, | |
1126 }; | |
277
a313e1080322
disable encoders where appropriate (patch courtesy of BERO
melanson
parents:
276
diff
changeset
|
1127 #endif //CONFIG_ENCODERS |
0 | 1128 |
190 | 1129 AVInputFormat mpegps_demux = { |
0 | 1130 "mpeg", |
1131 "MPEG PS format", | |
1132 sizeof(MpegDemuxContext), | |
1133 mpegps_probe, | |
1134 mpegps_read_header, | |
1135 mpegps_read_packet, | |
1136 mpegps_read_close, | |
310 | 1137 mpegps_read_seek, |
0 | 1138 }; |
1139 | |
1140 int mpegps_init(void) | |
1141 { | |
277
a313e1080322
disable encoders where appropriate (patch courtesy of BERO
melanson
parents:
276
diff
changeset
|
1142 #ifdef CONFIG_ENCODERS |
0 | 1143 av_register_output_format(&mpeg1system_mux); |
1144 av_register_output_format(&mpeg1vcd_mux); | |
1145 av_register_output_format(&mpeg2vob_mux); | |
277
a313e1080322
disable encoders where appropriate (patch courtesy of BERO
melanson
parents:
276
diff
changeset
|
1146 #endif //CONFIG_ENCODERS |
0 | 1147 av_register_input_format(&mpegps_demux); |
1148 return 0; | |
1149 } |