Mercurial > libavformat.hg
comparison 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 |
comparison
equal
deleted
inserted
replaced
336:d75fd4c6ab62 | 337:f6b2b0718235 |
---|---|
344 /* packet header size */ | 344 /* packet header size */ |
345 buf_index += 6; | 345 buf_index += 6; |
346 if (s->is_mpeg2) | 346 if (s->is_mpeg2) |
347 buf_index += 3; | 347 buf_index += 3; |
348 if (pts != AV_NOPTS_VALUE) { | 348 if (pts != AV_NOPTS_VALUE) { |
349 if (dts != AV_NOPTS_VALUE) | 349 if (dts != pts) |
350 buf_index += 5 + 5; | 350 buf_index += 5 + 5; |
351 else | 351 else |
352 buf_index += 5; | 352 buf_index += 5; |
353 } else { | 353 } else { |
354 if (!s->is_mpeg2) | 354 if (!s->is_mpeg2) |
408 header_len = 3; | 408 header_len = 3; |
409 } else { | 409 } else { |
410 header_len = 0; | 410 header_len = 0; |
411 } | 411 } |
412 if (pts != AV_NOPTS_VALUE) { | 412 if (pts != AV_NOPTS_VALUE) { |
413 if (dts != AV_NOPTS_VALUE) | 413 if (dts != pts) |
414 header_len += 5 + 5; | 414 header_len += 5 + 5; |
415 else | 415 else |
416 header_len += 5; | 416 header_len += 5; |
417 } else { | 417 } else { |
418 if (!s->is_mpeg2) | 418 if (!s->is_mpeg2) |
442 | 442 |
443 if (s->is_mpeg2) { | 443 if (s->is_mpeg2) { |
444 put_byte(&ctx->pb, 0x80); /* mpeg2 id */ | 444 put_byte(&ctx->pb, 0x80); /* mpeg2 id */ |
445 | 445 |
446 if (pts != AV_NOPTS_VALUE) { | 446 if (pts != AV_NOPTS_VALUE) { |
447 if (dts != AV_NOPTS_VALUE) { | 447 if (dts != pts) { |
448 put_byte(&ctx->pb, 0xc0); /* flags */ | 448 put_byte(&ctx->pb, 0xc0); /* flags */ |
449 put_byte(&ctx->pb, header_len - 3); | 449 put_byte(&ctx->pb, header_len - 3); |
450 put_timestamp(&ctx->pb, 0x03, pts); | 450 put_timestamp(&ctx->pb, 0x03, pts); |
451 put_timestamp(&ctx->pb, 0x01, dts); | 451 put_timestamp(&ctx->pb, 0x01, dts); |
452 } else { | 452 } else { |
458 put_byte(&ctx->pb, 0x00); /* flags */ | 458 put_byte(&ctx->pb, 0x00); /* flags */ |
459 put_byte(&ctx->pb, header_len - 3); | 459 put_byte(&ctx->pb, header_len - 3); |
460 } | 460 } |
461 } else { | 461 } else { |
462 if (pts != AV_NOPTS_VALUE) { | 462 if (pts != AV_NOPTS_VALUE) { |
463 if (dts != AV_NOPTS_VALUE) { | 463 if (dts != pts) { |
464 put_timestamp(&ctx->pb, 0x03, pts); | 464 put_timestamp(&ctx->pb, 0x03, pts); |
465 put_timestamp(&ctx->pb, 0x01, dts); | 465 put_timestamp(&ctx->pb, 0x01, dts); |
466 } else { | 466 } else { |
467 put_timestamp(&ctx->pb, 0x02, pts); | 467 put_timestamp(&ctx->pb, 0x02, pts); |
468 } | 468 } |
495 stream->packet_number++; | 495 stream->packet_number++; |
496 stream->nb_frames = 0; | 496 stream->nb_frames = 0; |
497 stream->frame_start_offset = 0; | 497 stream->frame_start_offset = 0; |
498 } | 498 } |
499 | 499 |
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 | |
500 static int mpeg_mux_write_packet(AVFormatContext *ctx, int stream_index, | 544 static int mpeg_mux_write_packet(AVFormatContext *ctx, int stream_index, |
501 const uint8_t *buf, int size, int64_t pts) | 545 const uint8_t *buf, int size, |
546 int64_t timestamp) | |
502 { | 547 { |
503 MpegMuxContext *s = ctx->priv_data; | 548 MpegMuxContext *s = ctx->priv_data; |
504 AVStream *st = ctx->streams[stream_index]; | 549 AVStream *st = ctx->streams[stream_index]; |
505 StreamInfo *stream = st->priv_data; | 550 StreamInfo *stream = st->priv_data; |
506 int64_t dts, new_start_pts, new_start_dts; | 551 int64_t pts, dts, new_start_pts, new_start_dts; |
507 int len, avail_size; | 552 int len, avail_size; |
553 | |
554 compute_pts_dts(st, &pts, &dts, timestamp); | |
508 | 555 |
509 /* XXX: system clock should be computed precisely, especially for | 556 /* XXX: system clock should be computed precisely, especially for |
510 CBR case. The current mode gives at least something coherent */ | 557 CBR case. The current mode gives at least something coherent */ |
511 if (stream_index == s->scr_stream_index) | 558 if (stream_index == s->scr_stream_index) |
512 s->last_scr = pts; | 559 s->last_scr = pts; |
513 | 560 |
514 #if 0 | 561 #if 0 |
515 printf("%d: pts=%0.3f scr=%0.3f\n", | 562 printf("%d: pts=%0.3f dts=%0.3f scr=%0.3f\n", |
516 stream_index, pts / 90000.0, s->last_scr / 90000.0); | 563 stream_index, |
564 pts / 90000.0, | |
565 dts / 90000.0, | |
566 s->last_scr / 90000.0); | |
517 #endif | 567 #endif |
518 | 568 |
519 /* XXX: currently no way to pass dts, will change soon */ | |
520 dts = AV_NOPTS_VALUE; | |
521 | |
522 /* we assume here that pts != AV_NOPTS_VALUE */ | 569 /* we assume here that pts != AV_NOPTS_VALUE */ |
523 new_start_pts = stream->start_pts; | 570 new_start_pts = stream->start_pts; |
524 new_start_dts = stream->start_dts; | 571 new_start_dts = stream->start_dts; |
525 | 572 |
526 if (stream->start_pts == AV_NOPTS_VALUE) { | 573 if (stream->start_pts == AV_NOPTS_VALUE) { |