Mercurial > libavformat.hg
annotate mpeg.c @ 337:f6b2b0718235 libavformat
harcoded DTS computation for mpeg
author | bellard |
---|---|
date | Thu, 18 Dec 2003 13:03:37 +0000 |
parents | d75fd4c6ab62 |
children | e154eb1b7149 |
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) { |
337 | 349 if (dts != pts) |
335
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
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) { |
337 | 413 if (dts != pts) |
331
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
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) { |
337 | 447 if (dts != pts) { |
331
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
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) { |
337 | 463 if (dts != pts) { |
331
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
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 | |
337 | 500 /* XXX: move that to upper layer */ |
501 /* XXX: we assume that there are always 'max_b_frames' between | |
502 reference frames. A better solution would be to use the AVFrame pts | |
503 field */ | |
504 static void compute_pts_dts(AVStream *st, int64_t *ppts, int64_t *pdts, | |
505 int64_t timestamp) | |
506 { | |
507 int frame_delay; | |
508 int64_t pts, dts; | |
509 | |
510 if (st->codec.codec_type == CODEC_TYPE_VIDEO && | |
511 st->codec.max_b_frames != 0) { | |
512 frame_delay = (st->codec.frame_rate_base * 90000LL) / | |
513 st->codec.frame_rate; | |
514 if (timestamp == 0) { | |
515 /* specific case for first frame : DTS just before */ | |
516 pts = timestamp; | |
517 dts = timestamp - frame_delay; | |
518 } else { | |
519 timestamp -= frame_delay; | |
520 if (st->codec.coded_frame->pict_type == FF_B_TYPE) { | |
521 /* B frames has identical pts/dts */ | |
522 pts = timestamp; | |
523 dts = timestamp; | |
524 } else { | |
525 /* a reference frame has a pts equal to the dts of the | |
526 _next_ one */ | |
527 dts = timestamp; | |
528 pts = timestamp + (st->codec.max_b_frames + 1) * frame_delay; | |
529 } | |
530 } | |
531 #if 1 | |
532 printf("pts=%0.3f dts=%0.3f pict_type=%c\n", | |
533 pts / 90000.0, dts / 90000.0, | |
534 av_get_pict_type_char(st->codec.coded_frame->pict_type)); | |
535 #endif | |
536 } else { | |
537 pts = timestamp; | |
538 dts = timestamp; | |
539 } | |
540 *ppts = pts & ((1LL << 33) - 1); | |
541 *pdts = dts & ((1LL << 33) - 1); | |
542 } | |
543 | |
0 | 544 static int mpeg_mux_write_packet(AVFormatContext *ctx, int stream_index, |
337 | 545 const uint8_t *buf, int size, |
546 int64_t timestamp) | |
0 | 547 { |
548 MpegMuxContext *s = ctx->priv_data; | |
549 AVStream *st = ctx->streams[stream_index]; | |
550 StreamInfo *stream = st->priv_data; | |
337 | 551 int64_t pts, dts, new_start_pts, new_start_dts; |
335
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
552 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
|
553 |
337 | 554 compute_pts_dts(st, &pts, &dts, timestamp); |
555 | |
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
|
556 /* 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
|
557 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
|
558 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
|
559 s->last_scr = pts; |
0 | 560 |
331
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
561 #if 0 |
337 | 562 printf("%d: pts=%0.3f dts=%0.3f scr=%0.3f\n", |
563 stream_index, | |
564 pts / 90000.0, | |
565 dts / 90000.0, | |
566 s->last_scr / 90000.0); | |
331
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
567 #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
|
568 |
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
569 /* 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
|
570 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
|
571 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
|
572 |
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
|
573 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
|
574 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
|
575 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
|
576 } |
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
|
577 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
|
578 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
|
579 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
|
580 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
|
581 /* 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
|
582 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
|
583 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
|
584 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
|
585 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
|
586 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
|
587 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
|
588 } |
b0ac206f232d
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
bellard
parents:
331
diff
changeset
|
589 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
|
590 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
|
591 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
|
592 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
|
593 stream->frame_start_offset = stream->buffer_ptr; |
0 | 594 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
|
595 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
|
596 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
|
597 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
|
598 len = avail_size - stream->buffer_ptr; |
0 | 599 if (len > size) |
600 len = size; | |
601 memcpy(stream->buffer + stream->buffer_ptr, buf, len); | |
602 stream->buffer_ptr += len; | |
603 buf += len; | |
604 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
|
605 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
|
606 /* 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
|
607 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
|
608 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
|
609 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
|
610 /* 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
|
611 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
|
612 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
|
613 stream->start_dts = AV_NOPTS_VALUE; |
0 | 614 } |
615 } | |
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
|
616 |
0 | 617 return 0; |
618 } | |
619 | |
620 static int mpeg_mux_end(AVFormatContext *ctx) | |
621 { | |
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
|
622 MpegMuxContext *s = ctx->priv_data; |
0 | 623 StreamInfo *stream; |
624 int i; | |
625 | |
626 /* flush each packet */ | |
627 for(i=0;i<ctx->nb_streams;i++) { | |
628 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
|
629 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
|
630 /* 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
|
631 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
|
632 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
|
633 s->last_scr); |
0 | 634 } |
635 } | |
636 | |
242 | 637 /* End header according to MPEG1 systems standard. We do not write |
638 it as it is usually not needed by decoders and because it | |
639 complicates MPEG stream concatenation. */ | |
0 | 640 //put_be32(&ctx->pb, ISO_11172_END_CODE); |
641 //put_flush_packet(&ctx->pb); | |
237
35231c0be8e5
memleak fix by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michaelni
parents:
210
diff
changeset
|
642 |
35231c0be8e5
memleak fix by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michaelni
parents:
210
diff
changeset
|
643 for(i=0;i<ctx->nb_streams;i++) |
35231c0be8e5
memleak fix by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michaelni
parents:
210
diff
changeset
|
644 av_freep(&ctx->streams[i]->priv_data); |
35231c0be8e5
memleak fix by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michaelni
parents:
210
diff
changeset
|
645 |
0 | 646 return 0; |
647 } | |
277
a313e1080322
disable encoders where appropriate (patch courtesy of BERO
melanson
parents:
276
diff
changeset
|
648 #endif //CONFIG_ENCODERS |
0 | 649 |
650 /*********************************************/ | |
651 /* demux code */ | |
652 | |
653 #define MAX_SYNC_SIZE 100000 | |
654 | |
655 static int mpegps_probe(AVProbeData *p) | |
656 { | |
165
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
657 int code, c, i; |
0 | 658 |
165
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
659 code = 0xff; |
0 | 660 /* we search the first start code. If it is a packet start code, |
661 then we decide it is mpeg ps. We do not send highest value to | |
662 give a chance to mpegts */ | |
49 | 663 /* NOTE: the search range was restricted to avoid too many false |
664 detections */ | |
665 | |
666 if (p->buf_size < 6) | |
667 return 0; | |
165
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
668 |
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
669 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
|
670 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
|
671 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
|
672 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
|
673 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
|
674 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
|
675 (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
|
676 (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
|
677 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
|
678 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
|
679 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
|
680 code == PADDING_STREAM) |
210 | 681 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
|
682 else |
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
683 return 0; |
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
684 } |
0 | 685 } |
686 return 0; | |
687 } | |
688 | |
689 | |
690 typedef struct MpegDemuxContext { | |
691 int header_state; | |
692 } MpegDemuxContext; | |
693 | |
310 | 694 static int mpegps_read_header(AVFormatContext *s, |
695 AVFormatParameters *ap) | |
696 { | |
697 MpegDemuxContext *m = s->priv_data; | |
698 m->header_state = 0xff; | |
699 s->ctx_flags |= AVFMTCTX_NOHEADER; | |
700 | |
701 /* no need to do more */ | |
702 return 0; | |
703 } | |
704 | |
705 static int64_t get_pts(ByteIOContext *pb, int c) | |
706 { | |
707 int64_t pts; | |
708 int val; | |
709 | |
710 if (c < 0) | |
711 c = get_byte(pb); | |
712 pts = (int64_t)((c >> 1) & 0x07) << 30; | |
713 val = get_be16(pb); | |
714 pts |= (int64_t)(val >> 1) << 15; | |
715 val = get_be16(pb); | |
716 pts |= (int64_t)(val >> 1); | |
717 return pts; | |
718 } | |
719 | |
720 static int find_next_start_code(ByteIOContext *pb, int *size_ptr, | |
721 uint32_t *header_state) | |
0 | 722 { |
723 unsigned int state, v; | |
724 int val, n; | |
725 | |
726 state = *header_state; | |
727 n = *size_ptr; | |
728 while (n > 0) { | |
729 if (url_feof(pb)) | |
730 break; | |
731 v = get_byte(pb); | |
732 n--; | |
733 if (state == 0x000001) { | |
734 state = ((state << 8) | v) & 0xffffff; | |
735 val = state; | |
736 goto found; | |
737 } | |
738 state = ((state << 8) | v) & 0xffffff; | |
739 } | |
740 val = -1; | |
741 found: | |
742 *header_state = state; | |
743 *size_ptr = n; | |
744 return val; | |
745 } | |
746 | |
310 | 747 /* XXX: optimize */ |
748 static int find_prev_start_code(ByteIOContext *pb, int *size_ptr) | |
0 | 749 { |
310 | 750 int64_t pos, pos_start; |
751 int max_size, start_code; | |
752 | |
753 max_size = *size_ptr; | |
754 pos_start = url_ftell(pb); | |
755 | |
756 /* in order to go faster, we fill the buffer */ | |
757 pos = pos_start - 16386; | |
758 if (pos < 0) | |
759 pos = 0; | |
760 url_fseek(pb, pos, SEEK_SET); | |
761 get_byte(pb); | |
293
62cec412a186
make AVFMT_NOHEADER flag dynamic - added av_open_input_stream()
bellard
parents:
291
diff
changeset
|
762 |
310 | 763 pos = pos_start; |
764 for(;;) { | |
765 pos--; | |
766 if (pos < 0 || (pos_start - pos) >= max_size) { | |
767 start_code = -1; | |
768 goto the_end; | |
769 } | |
770 url_fseek(pb, pos, SEEK_SET); | |
771 start_code = get_be32(pb); | |
772 if ((start_code & 0xffffff00) == 0x100) | |
773 break; | |
774 } | |
775 the_end: | |
776 *size_ptr = pos_start - pos; | |
777 return start_code; | |
0 | 778 } |
779 | |
310 | 780 /* read the next (or previous) PES header. Return its position in ppos |
781 (if not NULL), and its start code, pts and dts. | |
782 */ | |
783 static int mpegps_read_pes_header(AVFormatContext *s, | |
784 int64_t *ppos, int *pstart_code, | |
785 int64_t *ppts, int64_t *pdts, int find_next) | |
0 | 786 { |
787 MpegDemuxContext *m = s->priv_data; | |
310 | 788 int len, size, startcode, c, flags, header_len; |
789 int64_t pts, dts, last_pos; | |
0 | 790 |
310 | 791 last_pos = -1; |
0 | 792 redo: |
310 | 793 if (find_next) { |
794 /* next start code (should be immediately after) */ | |
795 m->header_state = 0xff; | |
796 size = MAX_SYNC_SIZE; | |
797 startcode = find_next_start_code(&s->pb, &size, &m->header_state); | |
798 } else { | |
799 if (last_pos >= 0) | |
800 url_fseek(&s->pb, last_pos, SEEK_SET); | |
801 size = MAX_SYNC_SIZE; | |
802 startcode = find_prev_start_code(&s->pb, &size); | |
803 last_pos = url_ftell(&s->pb) - 4; | |
804 } | |
0 | 805 //printf("startcode=%x pos=0x%Lx\n", startcode, url_ftell(&s->pb)); |
806 if (startcode < 0) | |
807 return -EIO; | |
808 if (startcode == PACK_START_CODE) | |
809 goto redo; | |
810 if (startcode == SYSTEM_HEADER_START_CODE) | |
811 goto redo; | |
812 if (startcode == PADDING_STREAM || | |
813 startcode == PRIVATE_STREAM_2) { | |
814 /* skip them */ | |
815 len = get_be16(&s->pb); | |
816 url_fskip(&s->pb, len); | |
817 goto redo; | |
818 } | |
819 /* find matching stream */ | |
820 if (!((startcode >= 0x1c0 && startcode <= 0x1df) || | |
821 (startcode >= 0x1e0 && startcode <= 0x1ef) || | |
822 (startcode == 0x1bd))) | |
823 goto redo; | |
310 | 824 if (ppos) { |
825 *ppos = url_ftell(&s->pb) - 4; | |
826 } | |
0 | 827 len = get_be16(&s->pb); |
828 pts = AV_NOPTS_VALUE; | |
829 dts = AV_NOPTS_VALUE; | |
830 /* stuffing */ | |
831 for(;;) { | |
310 | 832 if (len < 1) |
833 goto redo; | |
0 | 834 c = get_byte(&s->pb); |
835 len--; | |
836 /* XXX: for mpeg1, should test only bit 7 */ | |
837 if (c != 0xff) | |
838 break; | |
839 } | |
840 if ((c & 0xc0) == 0x40) { | |
841 /* buffer scale & size */ | |
310 | 842 if (len < 2) |
843 goto redo; | |
0 | 844 get_byte(&s->pb); |
845 c = get_byte(&s->pb); | |
846 len -= 2; | |
847 } | |
848 if ((c & 0xf0) == 0x20) { | |
310 | 849 if (len < 4) |
850 goto redo; | |
851 dts = pts = get_pts(&s->pb, c); | |
0 | 852 len -= 4; |
853 } else if ((c & 0xf0) == 0x30) { | |
310 | 854 if (len < 9) |
855 goto redo; | |
0 | 856 pts = get_pts(&s->pb, c); |
857 dts = get_pts(&s->pb, -1); | |
858 len -= 9; | |
859 } else if ((c & 0xc0) == 0x80) { | |
860 /* mpeg 2 PES */ | |
861 if ((c & 0x30) != 0) { | |
310 | 862 /* Encrypted multiplex not handled */ |
863 goto redo; | |
0 | 864 } |
865 flags = get_byte(&s->pb); | |
866 header_len = get_byte(&s->pb); | |
867 len -= 2; | |
868 if (header_len > len) | |
869 goto redo; | |
870 if ((flags & 0xc0) == 0x80) { | |
310 | 871 dts = pts = get_pts(&s->pb, -1); |
872 if (header_len < 5) | |
873 goto redo; | |
0 | 874 header_len -= 5; |
875 len -= 5; | |
876 } if ((flags & 0xc0) == 0xc0) { | |
877 pts = get_pts(&s->pb, -1); | |
878 dts = get_pts(&s->pb, -1); | |
310 | 879 if (header_len < 10) |
880 goto redo; | |
0 | 881 header_len -= 10; |
882 len -= 10; | |
883 } | |
884 len -= header_len; | |
885 while (header_len > 0) { | |
886 get_byte(&s->pb); | |
887 header_len--; | |
888 } | |
889 } | |
890 if (startcode == 0x1bd) { | |
310 | 891 if (len < 1) |
892 goto redo; | |
0 | 893 startcode = get_byte(&s->pb); |
894 len--; | |
895 if (startcode >= 0x80 && startcode <= 0xbf) { | |
896 /* audio: skip header */ | |
310 | 897 if (len < 3) |
898 goto redo; | |
0 | 899 get_byte(&s->pb); |
900 get_byte(&s->pb); | |
901 get_byte(&s->pb); | |
902 len -= 3; | |
903 } | |
904 } | |
310 | 905 *pstart_code = startcode; |
906 *ppts = pts; | |
907 *pdts = dts; | |
908 return len; | |
909 } | |
910 | |
911 static int mpegps_read_packet(AVFormatContext *s, | |
912 AVPacket *pkt) | |
913 { | |
914 AVStream *st; | |
915 int len, startcode, i, type, codec_id; | |
916 int64_t pts, dts; | |
917 | |
918 redo: | |
919 len = mpegps_read_pes_header(s, NULL, &startcode, &pts, &dts, 1); | |
920 if (len < 0) | |
921 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
|
922 |
0 | 923 /* now find stream */ |
924 for(i=0;i<s->nb_streams;i++) { | |
925 st = s->streams[i]; | |
926 if (st->id == startcode) | |
927 goto found; | |
928 } | |
929 if (startcode >= 0x1e0 && startcode <= 0x1ef) { | |
930 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
|
931 codec_id = CODEC_ID_MPEG2VIDEO; |
0 | 932 } else if (startcode >= 0x1c0 && startcode <= 0x1df) { |
933 type = CODEC_TYPE_AUDIO; | |
934 codec_id = CODEC_ID_MP2; | |
935 } else if (startcode >= 0x80 && startcode <= 0x9f) { | |
936 type = CODEC_TYPE_AUDIO; | |
937 codec_id = CODEC_ID_AC3; | |
41 | 938 } else if (startcode >= 0xa0 && startcode <= 0xbf) { |
939 type = CODEC_TYPE_AUDIO; | |
940 codec_id = CODEC_ID_PCM_S16BE; | |
0 | 941 } else { |
942 skip: | |
943 /* skip packet */ | |
944 url_fskip(&s->pb, len); | |
945 goto redo; | |
946 } | |
947 /* no stream found: add a new stream */ | |
948 st = av_new_stream(s, startcode); | |
949 if (!st) | |
950 goto skip; | |
951 st->codec.codec_type = type; | |
952 st->codec.codec_id = codec_id; | |
310 | 953 if (codec_id != CODEC_ID_PCM_S16BE) |
954 st->need_parsing = 1; | |
0 | 955 found: |
41 | 956 if (startcode >= 0xa0 && startcode <= 0xbf) { |
957 int b1, freq; | |
958 | |
959 /* for LPCM, we just skip the header and consider it is raw | |
960 audio data */ | |
961 if (len <= 3) | |
962 goto skip; | |
963 get_byte(&s->pb); /* emphasis (1), muse(1), reserved(1), frame number(5) */ | |
964 b1 = get_byte(&s->pb); /* quant (2), freq(2), reserved(1), channels(3) */ | |
965 get_byte(&s->pb); /* dynamic range control (0x80 = off) */ | |
966 len -= 3; | |
967 freq = (b1 >> 4) & 3; | |
968 st->codec.sample_rate = lpcm_freq_tab[freq]; | |
969 st->codec.channels = 1 + (b1 & 7); | |
970 st->codec.bit_rate = st->codec.channels * st->codec.sample_rate * 2; | |
971 } | |
0 | 972 av_new_packet(pkt, len); |
973 get_buffer(&s->pb, pkt->data, pkt->size); | |
974 pkt->pts = pts; | |
310 | 975 pkt->dts = dts; |
0 | 976 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
|
977 #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
|
978 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
|
979 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
|
980 #endif |
0 | 981 return 0; |
982 } | |
983 | |
984 static int mpegps_read_close(AVFormatContext *s) | |
985 { | |
986 return 0; | |
987 } | |
988 | |
310 | 989 static int64_t mpegps_read_dts(AVFormatContext *s, int stream_index, |
990 int64_t *ppos, int find_next) | |
991 { | |
992 int len, startcode; | |
993 int64_t pos, pts, dts; | |
994 | |
995 pos = *ppos; | |
996 #ifdef DEBUG_SEEK | |
997 printf("read_dts: pos=0x%llx next=%d -> ", pos, find_next); | |
998 #endif | |
999 url_fseek(&s->pb, pos, SEEK_SET); | |
1000 for(;;) { | |
1001 len = mpegps_read_pes_header(s, &pos, &startcode, &pts, &dts, find_next); | |
1002 if (len < 0) { | |
1003 #ifdef DEBUG_SEEK | |
1004 printf("none (ret=%d)\n", len); | |
1005 #endif | |
1006 return AV_NOPTS_VALUE; | |
1007 } | |
1008 if (startcode == s->streams[stream_index]->id && | |
1009 dts != AV_NOPTS_VALUE) { | |
1010 break; | |
1011 } | |
1012 if (find_next) { | |
1013 url_fskip(&s->pb, len); | |
1014 } else { | |
1015 url_fseek(&s->pb, pos, SEEK_SET); | |
1016 } | |
1017 } | |
1018 #ifdef DEBUG_SEEK | |
1019 printf("pos=0x%llx dts=0x%llx %0.3f\n", pos, dts, dts / 90000.0); | |
1020 #endif | |
1021 *ppos = pos; | |
1022 return dts; | |
1023 } | |
1024 | |
1025 static int find_stream_index(AVFormatContext *s) | |
1026 { | |
1027 int i; | |
1028 AVStream *st; | |
1029 | |
1030 if (s->nb_streams <= 0) | |
1031 return -1; | |
1032 for(i = 0; i < s->nb_streams; i++) { | |
1033 st = s->streams[i]; | |
1034 if (st->codec.codec_type == CODEC_TYPE_VIDEO) { | |
1035 return i; | |
1036 } | |
1037 } | |
1038 return 0; | |
1039 } | |
1040 | |
1041 static int mpegps_read_seek(AVFormatContext *s, | |
1042 int stream_index, int64_t timestamp) | |
1043 { | |
1044 int64_t pos_min, pos_max, pos; | |
1045 int64_t dts_min, dts_max, dts; | |
1046 | |
1047 timestamp = (timestamp * 90000) / AV_TIME_BASE; | |
1048 | |
1049 #ifdef DEBUG_SEEK | |
1050 printf("read_seek: %d %0.3f\n", stream_index, timestamp / 90000.0); | |
1051 #endif | |
1052 | |
1053 /* XXX: find stream_index by looking at the first PES packet found */ | |
1054 if (stream_index < 0) { | |
1055 stream_index = find_stream_index(s); | |
1056 if (stream_index < 0) | |
1057 return -1; | |
1058 } | |
1059 pos_min = 0; | |
1060 dts_min = mpegps_read_dts(s, stream_index, &pos_min, 1); | |
1061 if (dts_min == AV_NOPTS_VALUE) { | |
1062 /* we can reach this case only if no PTS are present in | |
1063 the whole stream */ | |
1064 return -1; | |
1065 } | |
1066 pos_max = url_filesize(url_fileno(&s->pb)) - 1; | |
1067 dts_max = mpegps_read_dts(s, stream_index, &pos_max, 0); | |
1068 | |
1069 while (pos_min <= pos_max) { | |
1070 #ifdef DEBUG_SEEK | |
1071 printf("pos_min=0x%llx pos_max=0x%llx dts_min=%0.3f dts_max=%0.3f\n", | |
1072 pos_min, pos_max, | |
1073 dts_min / 90000.0, dts_max / 90000.0); | |
1074 #endif | |
1075 if (timestamp <= dts_min) { | |
1076 pos = pos_min; | |
1077 goto found; | |
1078 } else if (timestamp >= dts_max) { | |
1079 pos = pos_max; | |
1080 goto found; | |
1081 } else { | |
1082 /* interpolate position (better than dichotomy) */ | |
1083 pos = (int64_t)((double)(pos_max - pos_min) * | |
1084 (double)(timestamp - dts_min) / | |
1085 (double)(dts_max - dts_min)) + pos_min; | |
1086 } | |
1087 #ifdef DEBUG_SEEK | |
1088 printf("pos=0x%llx\n", pos); | |
1089 #endif | |
1090 /* read the next timestamp */ | |
1091 dts = mpegps_read_dts(s, stream_index, &pos, 1); | |
1092 /* check if we are lucky */ | |
1093 if (dts == AV_NOPTS_VALUE) { | |
1094 /* should never happen */ | |
1095 pos = pos_min; | |
1096 goto found; | |
1097 } else if (timestamp == dts) { | |
1098 goto found; | |
1099 } else if (timestamp < dts) { | |
1100 pos_max = pos; | |
1101 dts_max = mpegps_read_dts(s, stream_index, &pos_max, 0); | |
1102 if (dts_max == AV_NOPTS_VALUE) { | |
1103 /* should never happen */ | |
1104 break; | |
1105 } else if (timestamp >= dts_max) { | |
1106 pos = pos_max; | |
1107 goto found; | |
1108 } | |
1109 } else { | |
1110 pos_min = pos + 1; | |
1111 dts_min = mpegps_read_dts(s, stream_index, &pos_min, 1); | |
1112 if (dts_min == AV_NOPTS_VALUE) { | |
1113 /* should never happen */ | |
1114 goto found; | |
1115 } else if (timestamp <= dts_min) { | |
1116 goto found; | |
1117 } | |
1118 } | |
1119 } | |
1120 pos = pos_min; | |
1121 found: | |
1122 #ifdef DEBUG_SEEK | |
1123 pos_min = pos; | |
1124 dts_min = mpegps_read_dts(s, stream_index, &pos_min, 1); | |
1125 pos_min++; | |
1126 dts_max = mpegps_read_dts(s, stream_index, &pos_min, 1); | |
1127 printf("pos=0x%llx %0.3f<=%0.3f<=%0.3f\n", | |
1128 pos, dts_min / 90000.0, timestamp / 90000.0, dts_max / 90000.0); | |
1129 #endif | |
1130 /* do the seek */ | |
1131 url_fseek(&s->pb, pos, SEEK_SET); | |
1132 return 0; | |
1133 } | |
1134 | |
277
a313e1080322
disable encoders where appropriate (patch courtesy of BERO
melanson
parents:
276
diff
changeset
|
1135 #ifdef CONFIG_ENCODERS |
0 | 1136 static AVOutputFormat mpeg1system_mux = { |
1137 "mpeg", | |
1138 "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
|
1139 "video/mpeg", |
0 | 1140 "mpg,mpeg", |
1141 sizeof(MpegMuxContext), | |
1142 CODEC_ID_MP2, | |
1143 CODEC_ID_MPEG1VIDEO, | |
1144 mpeg_mux_init, | |
1145 mpeg_mux_write_packet, | |
1146 mpeg_mux_end, | |
1147 }; | |
1148 | |
1149 static AVOutputFormat mpeg1vcd_mux = { | |
1150 "vcd", | |
1151 "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
|
1152 "video/mpeg", |
0 | 1153 NULL, |
1154 sizeof(MpegMuxContext), | |
1155 CODEC_ID_MP2, | |
1156 CODEC_ID_MPEG1VIDEO, | |
1157 mpeg_mux_init, | |
1158 mpeg_mux_write_packet, | |
1159 mpeg_mux_end, | |
1160 }; | |
1161 | |
1162 static AVOutputFormat mpeg2vob_mux = { | |
1163 "vob", | |
1164 "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
|
1165 "video/mpeg", |
0 | 1166 "vob", |
1167 sizeof(MpegMuxContext), | |
1168 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
|
1169 CODEC_ID_MPEG2VIDEO, |
0 | 1170 mpeg_mux_init, |
1171 mpeg_mux_write_packet, | |
1172 mpeg_mux_end, | |
1173 }; | |
277
a313e1080322
disable encoders where appropriate (patch courtesy of BERO
melanson
parents:
276
diff
changeset
|
1174 #endif //CONFIG_ENCODERS |
0 | 1175 |
190 | 1176 AVInputFormat mpegps_demux = { |
0 | 1177 "mpeg", |
1178 "MPEG PS format", | |
1179 sizeof(MpegDemuxContext), | |
1180 mpegps_probe, | |
1181 mpegps_read_header, | |
1182 mpegps_read_packet, | |
1183 mpegps_read_close, | |
310 | 1184 mpegps_read_seek, |
0 | 1185 }; |
1186 | |
1187 int mpegps_init(void) | |
1188 { | |
277
a313e1080322
disable encoders where appropriate (patch courtesy of BERO
melanson
parents:
276
diff
changeset
|
1189 #ifdef CONFIG_ENCODERS |
0 | 1190 av_register_output_format(&mpeg1system_mux); |
1191 av_register_output_format(&mpeg1vcd_mux); | |
1192 av_register_output_format(&mpeg2vob_mux); | |
277
a313e1080322
disable encoders where appropriate (patch courtesy of BERO
melanson
parents:
276
diff
changeset
|
1193 #endif //CONFIG_ENCODERS |
0 | 1194 av_register_input_format(&mpegps_demux); |
1195 return 0; | |
1196 } |