comparison mpeg.c @ 331:4530681af424 libavformat

suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
author bellard
date Tue, 09 Dec 2003 18:06:18 +0000
parents 944c8edaf609
children b0ac206f232d
comparison
equal deleted inserted replaced
330:c393ab803bcd 331:4530681af424
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */ 18 */
19 #include "avformat.h" 19 #include "avformat.h"
20 20
21 #define MAX_PAYLOAD_SIZE 4096 21 #define MAX_PAYLOAD_SIZE 4096
22 #define NB_STREAMS 2
23 //#define DEBUG_SEEK 22 //#define DEBUG_SEEK
24 23
25 typedef struct { 24 typedef struct {
26 uint8_t buffer[MAX_PAYLOAD_SIZE]; 25 uint8_t buffer[MAX_PAYLOAD_SIZE];
27 int buffer_ptr; 26 int buffer_ptr;
28 uint8_t id; 27 uint8_t id;
29 int max_buffer_size; /* in bytes */ 28 int max_buffer_size; /* in bytes */
30 int packet_number; 29 int packet_number;
31 int64_t start_pts; 30 int64_t start_pts;
31 int64_t start_dts;
32 } StreamInfo; 32 } StreamInfo;
33 33
34 typedef struct { 34 typedef struct {
35 int packet_size; /* required packet size */ 35 int packet_size; /* required packet size */
36 int packet_data_max_size; /* maximum data size inside a packet */ 36 int packet_data_max_size; /* maximum data size inside a packet */
41 /* stream info */ 41 /* stream info */
42 int audio_bound; 42 int audio_bound;
43 int video_bound; 43 int video_bound;
44 int is_mpeg2; 44 int is_mpeg2;
45 int is_vcd; 45 int is_vcd;
46 int scr_stream_index; /* stream from which the system clock is
47 computed (VBR case) */
48 int64_t last_scr; /* current system clock */
46 } MpegMuxContext; 49 } MpegMuxContext;
47 50
48 #define PACK_START_CODE ((unsigned int)0x000001ba) 51 #define PACK_START_CODE ((unsigned int)0x000001ba)
49 #define SYSTEM_HEADER_START_CODE ((unsigned int)0x000001bb) 52 #define SYSTEM_HEADER_START_CODE ((unsigned int)0x000001bb)
50 #define SEQUENCE_END_CODE ((unsigned int)0x000001b7) 53 #define SEQUENCE_END_CODE ((unsigned int)0x000001b7)
179 else 182 else
180 s->packet_size = 2048; 183 s->packet_size = 2048;
181 184
182 /* startcode(4) + length(2) + flags(1) */ 185 /* startcode(4) + length(2) + flags(1) */
183 s->packet_data_max_size = s->packet_size - 7; 186 s->packet_data_max_size = s->packet_size - 7;
187 if (s->is_mpeg2)
188 s->packet_data_max_size -= 2;
184 s->audio_bound = 0; 189 s->audio_bound = 0;
185 s->video_bound = 0; 190 s->video_bound = 0;
186 mpa_id = AUDIO_ID; 191 mpa_id = AUDIO_ID;
187 ac3_id = 0x80; 192 ac3_id = 0x80;
188 mpv_id = VIDEO_ID; 193 mpv_id = VIDEO_ID;
194 s->scr_stream_index = -1;
189 for(i=0;i<ctx->nb_streams;i++) { 195 for(i=0;i<ctx->nb_streams;i++) {
190 st = ctx->streams[i]; 196 st = ctx->streams[i];
191 stream = av_mallocz(sizeof(StreamInfo)); 197 stream = av_mallocz(sizeof(StreamInfo));
192 if (!stream) 198 if (!stream)
193 goto fail; 199 goto fail;
201 stream->id = mpa_id++; 207 stream->id = mpa_id++;
202 stream->max_buffer_size = 4 * 1024; 208 stream->max_buffer_size = 4 * 1024;
203 s->audio_bound++; 209 s->audio_bound++;
204 break; 210 break;
205 case CODEC_TYPE_VIDEO: 211 case CODEC_TYPE_VIDEO:
212 /* by default, video is used for the SCR computation */
213 if (s->scr_stream_index == -1)
214 s->scr_stream_index = i;
206 stream->id = mpv_id++; 215 stream->id = mpv_id++;
207 stream->max_buffer_size = 46 * 1024; 216 stream->max_buffer_size = 46 * 1024;
208 s->video_bound++; 217 s->video_bound++;
209 break; 218 break;
210 default: 219 default:
211 av_abort(); 220 av_abort();
212 } 221 }
213 } 222 }
223 /* if no SCR, use first stream (audio) */
224 if (s->scr_stream_index == -1)
225 s->scr_stream_index = 0;
214 226
215 /* we increase slightly the bitrate to take into account the 227 /* we increase slightly the bitrate to take into account the
216 headers. XXX: compute it exactly */ 228 headers. XXX: compute it exactly */
217 bitrate = 2000; 229 bitrate = 2000;
218 for(i=0;i<ctx->nb_streams;i++) { 230 for(i=0;i<ctx->nb_streams;i++) {
243 255
244 for(i=0;i<ctx->nb_streams;i++) { 256 for(i=0;i<ctx->nb_streams;i++) {
245 stream = ctx->streams[i]->priv_data; 257 stream = ctx->streams[i]->priv_data;
246 stream->buffer_ptr = 0; 258 stream->buffer_ptr = 0;
247 stream->packet_number = 0; 259 stream->packet_number = 0;
248 stream->start_pts = -1; 260 stream->start_pts = AV_NOPTS_VALUE;
249 } 261 stream->start_dts = AV_NOPTS_VALUE;
262 }
263 s->last_scr = 0;
250 return 0; 264 return 0;
251 fail: 265 fail:
252 for(i=0;i<ctx->nb_streams;i++) { 266 for(i=0;i<ctx->nb_streams;i++) {
253 av_free(ctx->streams[i]->priv_data); 267 av_free(ctx->streams[i]->priv_data);
254 } 268 }
255 return -ENOMEM; 269 return -ENOMEM;
256 } 270 }
257 271
272 static inline void put_timestamp(ByteIOContext *pb, int id, int64_t timestamp)
273 {
274 put_byte(pb,
275 (id << 4) |
276 (((timestamp >> 30) & 0x07) << 1) |
277 1);
278 put_be16(pb, (uint16_t)((((timestamp >> 15) & 0x7fff) << 1) | 1));
279 put_be16(pb, (uint16_t)((((timestamp) & 0x7fff) << 1) | 1));
280 }
281
258 /* flush the packet on stream stream_index */ 282 /* flush the packet on stream stream_index */
259 static void flush_packet(AVFormatContext *ctx, int stream_index) 283 static void flush_packet(AVFormatContext *ctx, int stream_index,
284 int64_t pts, int64_t dts, int64_t scr)
260 { 285 {
261 MpegMuxContext *s = ctx->priv_data; 286 MpegMuxContext *s = ctx->priv_data;
262 StreamInfo *stream = ctx->streams[stream_index]->priv_data; 287 StreamInfo *stream = ctx->streams[stream_index]->priv_data;
263 uint8_t *buf_ptr; 288 uint8_t *buf_ptr;
264 int size, payload_size, startcode, id, len, stuffing_size, i, header_len; 289 int size, payload_size, startcode, id, len, stuffing_size, i, header_len;
265 int64_t timestamp;
266 uint8_t buffer[128]; 290 uint8_t buffer[128];
267 291
268 id = stream->id; 292 id = stream->id;
269 timestamp = stream->start_pts; 293
270
271 #if 0 294 #if 0
272 printf("packet ID=%2x PTS=%0.3f\n", 295 printf("packet ID=%2x PTS=%0.3f\n",
273 id, timestamp / 90000.0); 296 id, pts / 90000.0);
274 #endif 297 #endif
275 298
276 buf_ptr = buffer; 299 buf_ptr = buffer;
277 if (((s->packet_number % s->pack_header_freq) == 0)) { 300 if (((s->packet_number % s->pack_header_freq) == 0)) {
278 /* output pack and systems header if needed */ 301 /* output pack and systems header if needed */
279 size = put_pack_header(ctx, buf_ptr, timestamp); 302 size = put_pack_header(ctx, buf_ptr, scr);
280 buf_ptr += size; 303 buf_ptr += size;
281 if ((s->packet_number % s->system_header_freq) == 0) { 304 if ((s->packet_number % s->system_header_freq) == 0) {
282 size = put_system_header(ctx, buf_ptr); 305 size = put_system_header(ctx, buf_ptr);
283 buf_ptr += size; 306 buf_ptr += size;
284 } 307 }
286 size = buf_ptr - buffer; 309 size = buf_ptr - buffer;
287 put_buffer(&ctx->pb, buffer, size); 310 put_buffer(&ctx->pb, buffer, size);
288 311
289 /* packet header */ 312 /* packet header */
290 if (s->is_mpeg2) { 313 if (s->is_mpeg2) {
291 header_len = 8; 314 header_len = 3;
292 } else { 315 } else {
293 header_len = 5; 316 header_len = 0;
294 } 317 }
318 if (pts != AV_NOPTS_VALUE) {
319 if (dts != AV_NOPTS_VALUE)
320 header_len += 5 + 5;
321 else
322 header_len += 5;
323 } else {
324 if (!s->is_mpeg2)
325 header_len++;
326 }
327
295 payload_size = s->packet_size - (size + 6 + header_len); 328 payload_size = s->packet_size - (size + 6 + header_len);
296 if (id < 0xc0) { 329 if (id < 0xc0) {
297 startcode = PRIVATE_STREAM_1; 330 startcode = PRIVATE_STREAM_1;
298 payload_size -= 4; 331 payload_size -= 4;
299 } else { 332 } else {
310 for(i=0;i<stuffing_size;i++) 343 for(i=0;i<stuffing_size;i++)
311 put_byte(&ctx->pb, 0xff); 344 put_byte(&ctx->pb, 0xff);
312 345
313 if (s->is_mpeg2) { 346 if (s->is_mpeg2) {
314 put_byte(&ctx->pb, 0x80); /* mpeg2 id */ 347 put_byte(&ctx->pb, 0x80); /* mpeg2 id */
315 put_byte(&ctx->pb, 0x80); /* flags */ 348
316 put_byte(&ctx->pb, 0x05); /* header len (only pts is included) */ 349 if (pts != AV_NOPTS_VALUE) {
317 } 350 if (dts != AV_NOPTS_VALUE) {
318 put_byte(&ctx->pb, 351 put_byte(&ctx->pb, 0xc0); /* flags */
319 (0x02 << 4) | 352 put_byte(&ctx->pb, header_len - 3);
320 (((timestamp >> 30) & 0x07) << 1) | 353 put_timestamp(&ctx->pb, 0x03, pts);
321 1); 354 put_timestamp(&ctx->pb, 0x01, dts);
322 put_be16(&ctx->pb, (uint16_t)((((timestamp >> 15) & 0x7fff) << 1) | 1)); 355 } else {
323 put_be16(&ctx->pb, (uint16_t)((((timestamp) & 0x7fff) << 1) | 1)); 356 put_byte(&ctx->pb, 0x80); /* flags */
357 put_byte(&ctx->pb, header_len - 3);
358 put_timestamp(&ctx->pb, 0x02, pts);
359 }
360 } else {
361 put_byte(&ctx->pb, 0x00); /* flags */
362 put_byte(&ctx->pb, header_len - 3);
363 }
364 } else {
365 if (pts != AV_NOPTS_VALUE) {
366 if (dts != AV_NOPTS_VALUE) {
367 put_timestamp(&ctx->pb, 0x03, pts);
368 put_timestamp(&ctx->pb, 0x01, dts);
369 } else {
370 put_timestamp(&ctx->pb, 0x02, pts);
371 }
372 } else {
373 put_byte(&ctx->pb, 0x0f);
374 }
375 }
324 376
325 if (startcode == PRIVATE_STREAM_1) { 377 if (startcode == PRIVATE_STREAM_1) {
326 put_byte(&ctx->pb, id); 378 put_byte(&ctx->pb, id);
327 if (id >= 0x80 && id <= 0xbf) { 379 if (id >= 0x80 && id <= 0xbf) {
328 /* XXX: need to check AC3 spec */ 380 /* XXX: need to check AC3 spec */
343 memmove(stream->buffer, stream->buffer + stream->buffer_ptr - len, len); 395 memmove(stream->buffer, stream->buffer + stream->buffer_ptr - len, len);
344 stream->buffer_ptr = len; 396 stream->buffer_ptr = len;
345 397
346 s->packet_number++; 398 s->packet_number++;
347 stream->packet_number++; 399 stream->packet_number++;
348 stream->start_pts = -1;
349 } 400 }
350 401
351 static int mpeg_mux_write_packet(AVFormatContext *ctx, int stream_index, 402 static int mpeg_mux_write_packet(AVFormatContext *ctx, int stream_index,
352 const uint8_t *buf, int size, int64_t pts) 403 const uint8_t *buf, int size, int64_t pts)
353 { 404 {
354 MpegMuxContext *s = ctx->priv_data; 405 MpegMuxContext *s = ctx->priv_data;
355 AVStream *st = ctx->streams[stream_index]; 406 AVStream *st = ctx->streams[stream_index];
356 StreamInfo *stream = st->priv_data; 407 StreamInfo *stream = st->priv_data;
408 int64_t dts;
357 int len; 409 int len;
358 410
411 /* XXX: system clock should be computed precisely, especially for
412 CBR case. The current mode gives at least something coherent */
413 if (stream_index == s->scr_stream_index)
414 s->last_scr = pts;
415
416 #if 0
417 printf("%d: pts=%0.3f scr=%0.3f\n",
418 stream_index, pts / 90000.0, s->last_scr / 90000.0);
419 #endif
420
421 /* XXX: currently no way to pass dts, will change soon */
422 dts = AV_NOPTS_VALUE;
423
424 /* we assume here that pts != AV_NOPTS_VALUE */
425 if (stream->start_pts == AV_NOPTS_VALUE) {
426 stream->start_pts = pts;
427 stream->start_dts = dts;
428 }
359 while (size > 0) { 429 while (size > 0) {
360 /* set pts */
361 if (stream->start_pts == -1) {
362 stream->start_pts = pts;
363 }
364 len = s->packet_data_max_size - stream->buffer_ptr; 430 len = s->packet_data_max_size - stream->buffer_ptr;
365 if (len > size) 431 if (len > size)
366 len = size; 432 len = size;
367 memcpy(stream->buffer + stream->buffer_ptr, buf, len); 433 memcpy(stream->buffer + stream->buffer_ptr, buf, len);
368 stream->buffer_ptr += len; 434 stream->buffer_ptr += len;
369 buf += len; 435 buf += len;
370 size -= len; 436 size -= len;
371 while (stream->buffer_ptr >= s->packet_data_max_size) { 437 while (stream->buffer_ptr >= s->packet_data_max_size) {
372 /* output the packet */ 438 /* output the packet */
373 if (stream->start_pts == -1) 439 flush_packet(ctx, stream_index,
374 stream->start_pts = pts; 440 stream->start_pts, stream->start_dts, s->last_scr);
375 flush_packet(ctx, stream_index); 441 /* Make sure only the FIRST pes packet for this frame has
442 a timestamp */
443 stream->start_pts = AV_NOPTS_VALUE;
444 stream->start_dts = AV_NOPTS_VALUE;
376 } 445 }
377 } 446 }
378 return 0; 447 return 0;
379 } 448 }
380 449
381 static int mpeg_mux_end(AVFormatContext *ctx) 450 static int mpeg_mux_end(AVFormatContext *ctx)
382 { 451 {
452 MpegMuxContext *s = ctx->priv_data;
383 StreamInfo *stream; 453 StreamInfo *stream;
384 int i; 454 int i;
385 455
386 /* flush each packet */ 456 /* flush each packet */
387 for(i=0;i<ctx->nb_streams;i++) { 457 for(i=0;i<ctx->nb_streams;i++) {
388 stream = ctx->streams[i]->priv_data; 458 stream = ctx->streams[i]->priv_data;
389 if (stream->buffer_ptr > 0) { 459 while (stream->buffer_ptr > 0) {
390 flush_packet(ctx, i); 460 flush_packet(ctx, i, AV_NOPTS_VALUE, AV_NOPTS_VALUE, s->last_scr);
391 } 461 }
392 } 462 }
393 463
394 /* End header according to MPEG1 systems standard. We do not write 464 /* End header according to MPEG1 systems standard. We do not write
395 it as it is usually not needed by decoders and because it 465 it as it is usually not needed by decoders and because it
674 744
675 redo: 745 redo:
676 len = mpegps_read_pes_header(s, NULL, &startcode, &pts, &dts, 1); 746 len = mpegps_read_pes_header(s, NULL, &startcode, &pts, &dts, 1);
677 if (len < 0) 747 if (len < 0)
678 return len; 748 return len;
679 749
680 /* now find stream */ 750 /* now find stream */
681 for(i=0;i<s->nb_streams;i++) { 751 for(i=0;i<s->nb_streams;i++) {
682 st = s->streams[i]; 752 st = s->streams[i];
683 if (st->id == startcode) 753 if (st->id == startcode)
684 goto found; 754 goto found;
726 st->codec.sample_rate = lpcm_freq_tab[freq]; 796 st->codec.sample_rate = lpcm_freq_tab[freq];
727 st->codec.channels = 1 + (b1 & 7); 797 st->codec.channels = 1 + (b1 & 7);
728 st->codec.bit_rate = st->codec.channels * st->codec.sample_rate * 2; 798 st->codec.bit_rate = st->codec.channels * st->codec.sample_rate * 2;
729 } 799 }
730 av_new_packet(pkt, len); 800 av_new_packet(pkt, len);
731 //printf("\nRead Packet ID: %x PTS: %f Size: %d", startcode,
732 // (float)pts/90000, len);
733 get_buffer(&s->pb, pkt->data, pkt->size); 801 get_buffer(&s->pb, pkt->data, pkt->size);
734 pkt->pts = pts; 802 pkt->pts = pts;
735 pkt->dts = dts; 803 pkt->dts = dts;
736 pkt->stream_index = st->index; 804 pkt->stream_index = st->index;
805 #if 0
806 printf("%d: pts=%0.3f dts=%0.3f\n",
807 pkt->stream_index, pkt->pts / 90000.0, pkt->dts / 90000.0);
808 #endif
737 return 0; 809 return 0;
738 } 810 }
739 811
740 static int mpegps_read_close(AVFormatContext *s) 812 static int mpegps_read_close(AVFormatContext *s)
741 { 813 {