Mercurial > libavformat.hg
comparison mpegtsenc.c @ 1838:d1af40ab8ea5 libavformat
write DTS, based on patch by Luca Abeni, lucabe72 email it
author | mru |
---|---|
date | Fri, 02 Mar 2007 21:47:24 +0000 |
parents | 3b00fb8ef8e4 |
children | d52c718e83f9 |
comparison
equal
deleted
inserted
replaced
1837:7b64dd81b38d | 1838:d1af40ab8ea5 |
---|---|
141 struct MpegTSService *service; | 141 struct MpegTSService *service; |
142 int pid; /* stream associated pid */ | 142 int pid; /* stream associated pid */ |
143 int cc; | 143 int cc; |
144 int payload_index; | 144 int payload_index; |
145 int64_t payload_pts; | 145 int64_t payload_pts; |
146 int64_t payload_dts; | |
146 uint8_t payload[DEFAULT_PES_PAYLOAD_SIZE]; | 147 uint8_t payload[DEFAULT_PES_PAYLOAD_SIZE]; |
147 } MpegTSWriteStream; | 148 } MpegTSWriteStream; |
148 | 149 |
149 typedef struct MpegTSService { | 150 typedef struct MpegTSService { |
150 MpegTSSection pmt; /* MPEG2 pmt table context */ | 151 MpegTSSection pmt; /* MPEG2 pmt table context */ |
394 goto fail; | 395 goto fail; |
395 st->priv_data = ts_st; | 396 st->priv_data = ts_st; |
396 ts_st->service = service; | 397 ts_st->service = service; |
397 ts_st->pid = DEFAULT_START_PID + i; | 398 ts_st->pid = DEFAULT_START_PID + i; |
398 ts_st->payload_pts = AV_NOPTS_VALUE; | 399 ts_st->payload_pts = AV_NOPTS_VALUE; |
400 ts_st->payload_dts = AV_NOPTS_VALUE; | |
399 /* update PCR pid by using the first video stream */ | 401 /* update PCR pid by using the first video stream */ |
400 if (st->codec->codec_type == CODEC_TYPE_VIDEO && | 402 if (st->codec->codec_type == CODEC_TYPE_VIDEO && |
401 service->pcr_pid == 0x1fff) | 403 service->pcr_pid == 0x1fff) |
402 service->pcr_pid = ts_st->pid; | 404 service->pcr_pid = ts_st->pid; |
403 total_bit_rate += st->codec->bit_rate; | 405 total_bit_rate += st->codec->bit_rate; |
458 mpegts_write_pmt(s, ts->services[i]); | 460 mpegts_write_pmt(s, ts->services[i]); |
459 } | 461 } |
460 } | 462 } |
461 } | 463 } |
462 | 464 |
465 static void write_pts(uint8_t *q, int fourbits, int64_t pts) | |
466 { | |
467 int val; | |
468 | |
469 val = fourbits << 4 | (((pts >> 30) & 0x07) << 1) | 1; | |
470 *q++ = val; | |
471 val = (((pts >> 15) & 0x7fff) << 1) | 1; | |
472 *q++ = val >> 8; | |
473 *q++ = val; | |
474 val = (((pts) & 0x7fff) << 1) | 1; | |
475 *q++ = val >> 8; | |
476 *q++ = val; | |
477 } | |
478 | |
463 /* NOTE: pes_data contains all the PES packet */ | 479 /* NOTE: pes_data contains all the PES packet */ |
464 static void mpegts_write_pes(AVFormatContext *s, AVStream *st, | 480 static void mpegts_write_pes(AVFormatContext *s, AVStream *st, |
465 const uint8_t *payload, int payload_size, | 481 const uint8_t *payload, int payload_size, |
466 int64_t pts) | 482 int64_t pts, int64_t dts) |
467 { | 483 { |
468 MpegTSWriteStream *ts_st = st->priv_data; | 484 MpegTSWriteStream *ts_st = st->priv_data; |
469 uint8_t buf[TS_PACKET_SIZE]; | 485 uint8_t buf[TS_PACKET_SIZE]; |
470 uint8_t *q; | 486 uint8_t *q; |
471 int val, is_start, len, header_len, write_pcr, private_code; | 487 int val, is_start, len, header_len, write_pcr, private_code, flags; |
472 int afc_len, stuffing_len; | 488 int afc_len, stuffing_len; |
473 int64_t pcr = -1; /* avoid warning */ | 489 int64_t pcr = -1; /* avoid warning */ |
474 | 490 |
475 is_start = 1; | 491 is_start = 1; |
476 while (payload_size > 0) { | 492 while (payload_size > 0) { |
525 *q++ = 0xbd; | 541 *q++ = 0xbd; |
526 if (st->codec->codec_type == CODEC_TYPE_SUBTITLE) { | 542 if (st->codec->codec_type == CODEC_TYPE_SUBTITLE) { |
527 private_code = 0x20; | 543 private_code = 0x20; |
528 } | 544 } |
529 } | 545 } |
530 if (pts != AV_NOPTS_VALUE) | 546 header_len = 0; |
531 header_len = 8; | 547 flags = 0; |
532 else | 548 if (pts != AV_NOPTS_VALUE) { |
533 header_len = 3; | 549 header_len += 5; |
550 flags |= 0x80; | |
551 } | |
552 if (dts != AV_NOPTS_VALUE) { | |
553 header_len += 5; | |
554 flags |= 0x40; | |
555 } | |
556 len = payload_size + header_len + 3; | |
534 if (private_code != 0) | 557 if (private_code != 0) |
535 header_len++; | 558 len++; |
536 len = payload_size + header_len; | |
537 *q++ = len >> 8; | 559 *q++ = len >> 8; |
538 *q++ = len; | 560 *q++ = len; |
539 val = 0x80; | 561 val = 0x80; |
540 /* data alignment indicator is required for subtitle data */ | 562 /* data alignment indicator is required for subtitle data */ |
541 if (st->codec->codec_type == CODEC_TYPE_SUBTITLE) | 563 if (st->codec->codec_type == CODEC_TYPE_SUBTITLE) |
542 val |= 0x04; | 564 val |= 0x04; |
543 *q++ = val; | 565 *q++ = val; |
566 *q++ = flags; | |
567 *q++ = header_len; | |
544 if (pts != AV_NOPTS_VALUE) { | 568 if (pts != AV_NOPTS_VALUE) { |
545 *q++ = 0x80; /* PTS only */ | 569 write_pts(q, flags >> 6, pts); |
546 *q++ = 0x05; /* header len */ | 570 q += 5; |
547 val = (0x02 << 4) | | 571 } |
548 (((pts >> 30) & 0x07) << 1) | 1; | 572 if (dts != AV_NOPTS_VALUE) { |
549 *q++ = val; | 573 write_pts(q, 1, dts); |
550 val = (((pts >> 15) & 0x7fff) << 1) | 1; | 574 q += 5; |
551 *q++ = val >> 8; | |
552 *q++ = val; | |
553 val = (((pts) & 0x7fff) << 1) | 1; | |
554 *q++ = val >> 8; | |
555 *q++ = val; | |
556 } else { | |
557 *q++ = 0x00; | |
558 *q++ = 0x00; | |
559 } | 575 } |
560 if (private_code != 0) | 576 if (private_code != 0) |
561 *q++ = private_code; | 577 *q++ = private_code; |
562 is_start = 0; | 578 is_start = 0; |
563 } | 579 } |
605 MpegTSWriteStream *ts_st = st->priv_data; | 621 MpegTSWriteStream *ts_st = st->priv_data; |
606 int len, max_payload_size; | 622 int len, max_payload_size; |
607 | 623 |
608 if (st->codec->codec_type == CODEC_TYPE_SUBTITLE) { | 624 if (st->codec->codec_type == CODEC_TYPE_SUBTITLE) { |
609 /* for subtitle, a single PES packet must be generated */ | 625 /* for subtitle, a single PES packet must be generated */ |
610 mpegts_write_pes(s, st, buf, size, pkt->pts); | 626 mpegts_write_pes(s, st, buf, size, pkt->pts, AV_NOPTS_VALUE); |
611 return 0; | 627 return 0; |
612 } | 628 } |
613 | 629 |
614 max_payload_size = DEFAULT_PES_PAYLOAD_SIZE; | 630 max_payload_size = DEFAULT_PES_PAYLOAD_SIZE; |
615 while (size > 0) { | 631 while (size > 0) { |
620 buf += len; | 636 buf += len; |
621 size -= len; | 637 size -= len; |
622 ts_st->payload_index += len; | 638 ts_st->payload_index += len; |
623 if (ts_st->payload_pts == AV_NOPTS_VALUE) | 639 if (ts_st->payload_pts == AV_NOPTS_VALUE) |
624 ts_st->payload_pts = pkt->pts; | 640 ts_st->payload_pts = pkt->pts; |
641 if (ts_st->payload_dts == AV_NOPTS_VALUE) | |
642 ts_st->payload_dts = pkt->dts; | |
625 if (ts_st->payload_index >= max_payload_size) { | 643 if (ts_st->payload_index >= max_payload_size) { |
626 mpegts_write_pes(s, st, ts_st->payload, ts_st->payload_index, | 644 mpegts_write_pes(s, st, ts_st->payload, ts_st->payload_index, |
627 ts_st->payload_pts); | 645 ts_st->payload_pts, ts_st->payload_dts); |
628 ts_st->payload_pts = AV_NOPTS_VALUE; | 646 ts_st->payload_pts = AV_NOPTS_VALUE; |
647 ts_st->payload_dts = AV_NOPTS_VALUE; | |
629 ts_st->payload_index = 0; | 648 ts_st->payload_index = 0; |
630 } | 649 } |
631 } | 650 } |
632 return 0; | 651 return 0; |
633 } | 652 } |
644 for(i = 0; i < s->nb_streams; i++) { | 663 for(i = 0; i < s->nb_streams; i++) { |
645 st = s->streams[i]; | 664 st = s->streams[i]; |
646 ts_st = st->priv_data; | 665 ts_st = st->priv_data; |
647 if (ts_st->payload_index > 0) { | 666 if (ts_st->payload_index > 0) { |
648 mpegts_write_pes(s, st, ts_st->payload, ts_st->payload_index, | 667 mpegts_write_pes(s, st, ts_st->payload, ts_st->payload_index, |
649 ts_st->payload_pts); | 668 ts_st->payload_pts, ts_st->payload_dts); |
650 } | 669 } |
651 } | 670 } |
652 put_flush_packet(&s->pb); | 671 put_flush_packet(&s->pb); |
653 | 672 |
654 for(i = 0; i < ts->nb_services; i++) { | 673 for(i = 0; i < ts->nb_services; i++) { |