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) {