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