srs_kernel_ts.hpp 73.3 KB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676
/*
The MIT License (MIT)

Copyright (c) 2013-2015 SRS(ossrs)

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#ifndef SRS_KERNEL_TS_HPP
#define SRS_KERNEL_TS_HPP

/*
#include <srs_kernel_ts.hpp>
*/
#include <srs_core.hpp>

#if !defined(SRS_EXPORT_LIBRTMP)

#include <string>
#include <map>
#include <vector>

#include <srs_kernel_codec.hpp>

class SrsStream;
class SrsTsCache;
class SrsTSMuxer;
class SrsFileWriter;
class SrsFileReader;
class SrsAvcAacCodec;
class SrsCodecSample;
class SrsSimpleBuffer;
class SrsTsAdaptationField;
class SrsTsPayload;
class SrsTsMessage;
class SrsTsPacket;
class SrsTsContext;

// Transport Stream packets are 188 bytes in length.
#define SRS_TS_PACKET_SIZE          188

// the aggregate pure audio for hls, in ts tbn(ms * 90).
#define SRS_CONSTS_HLS_PURE_AUDIO_AGGREGATE 720 * 90

/**
* the pid of ts packet,
* Table 2-3 - PID table, hls-mpeg-ts-iso13818-1.pdf, page 37
* NOTE - The transport packets with PID values 0x0000, 0x0001, and 0x0010-0x1FFE are allowed to carry a PCR.
*/
enum SrsTsPid
{
    // Program Association Table(see Table 2-25).
    SrsTsPidPAT             = 0x00,
    // Conditional Access Table (see Table 2-27).
    SrsTsPidCAT             = 0x01,
    // Transport Stream Description Table
    SrsTsPidTSDT            = 0x02,
    // Reserved
    SrsTsPidReservedStart   = 0x03,
    SrsTsPidReservedEnd     = 0x0f,
    // May be assigned as network_PID, Program_map_PID, elementary_PID, or for other purposes
    SrsTsPidAppStart        = 0x10,
    SrsTsPidAppEnd          = 0x1ffe,
    // null packets (see Table 2-3)
    SrsTsPidNULL    = 0x01FFF,
};

/**
* the transport_scrambling_control of ts packet,
* Table 2-4 - Scrambling control values, hls-mpeg-ts-iso13818-1.pdf, page 38
*/
enum SrsTsScrambled
{
    // Not scrambled
    SrsTsScrambledDisabled      = 0x00,
    // User-defined
    SrsTsScrambledUserDefined1  = 0x01,
    // User-defined
    SrsTsScrambledUserDefined2  = 0x02,
    // User-defined
    SrsTsScrambledUserDefined3  = 0x03,
};

/**
* the adaption_field_control of ts packet,
* Table 2-5 - Adaptation field control values, hls-mpeg-ts-iso13818-1.pdf, page 38
*/
enum SrsTsAdaptationFieldType
{
    // Reserved for future use by ISO/IEC
    SrsTsAdaptationFieldTypeReserved      = 0x00,
    // No adaptation_field, payload only
    SrsTsAdaptationFieldTypePayloadOnly   = 0x01,
    // Adaptation_field only, no payload
    SrsTsAdaptationFieldTypeAdaptionOnly  = 0x02,
    // Adaptation_field followed by payload
    SrsTsAdaptationFieldTypeBoth          = 0x03,
};

/**
* the actually parsed ts pid,
* @see SrsTsPid, some pid, for example, PMT/Video/Audio is specified by PAT or other tables.
*/
enum SrsTsPidApply
{
    SrsTsPidApplyReserved = 0, // TSPidTypeReserved, nothing parsed, used reserved.
    
    SrsTsPidApplyPAT, // Program associtate table
    SrsTsPidApplyPMT, // Program map table.
    
    SrsTsPidApplyVideo, // for video
    SrsTsPidApplyAudio, // vor audio
};

/**
* Table 2-29 - Stream type assignments
*/
enum SrsTsStream
{
    // ITU-T | ISO/IEC Reserved
    SrsTsStreamReserved         = 0x00,
    // ISO/IEC 11172 Video
    // ITU-T Rec. H.262 | ISO/IEC 13818-2 Video or ISO/IEC 11172-2 constrained parameter video stream
    // ISO/IEC 11172 Audio
    // ISO/IEC 13818-3 Audio
    SrsTsStreamAudioMp3         = 0x04,
    // ITU-T Rec. H.222.0 | ISO/IEC 13818-1 private_sections
    // ITU-T Rec. H.222.0 | ISO/IEC 13818-1 PES packets containing private data
    // ISO/IEC 13522 MHEG
    // ITU-T Rec. H.222.0 | ISO/IEC 13818-1 Annex A DSM-CC
    // ITU-T Rec. H.222.1
    // ISO/IEC 13818-6 type A
    // ISO/IEC 13818-6 type B
    // ISO/IEC 13818-6 type C
    // ISO/IEC 13818-6 type D
    // ITU-T Rec. H.222.0 | ISO/IEC 13818-1 auxiliary
    // ISO/IEC 13818-7 Audio with ADTS transport syntax
    SrsTsStreamAudioAAC        = 0x0f,
    // ISO/IEC 14496-2 Visual
    SrsTsStreamVideoMpeg4      = 0x10,
    // ISO/IEC 14496-3 Audio with the LATM transport syntax as defined in ISO/IEC 14496-3 / AMD 1
    SrsTsStreamAudioMpeg4      = 0x11,
    // ISO/IEC 14496-1 SL-packetized stream or FlexMux stream carried in PES packets
    // ISO/IEC 14496-1 SL-packetized stream or FlexMux stream carried in ISO/IEC14496_sections.
    // ISO/IEC 13818-6 Synchronized Download Protocol
    // ITU-T Rec. H.222.0 | ISO/IEC 13818-1 Reserved
    // 0x15-0x7F
    SrsTsStreamVideoH264       = 0x1b,
    // User Private
    // 0x80-0xFF
    SrsTsStreamAudioAC3        = 0x81,
    SrsTsStreamAudioDTS        = 0x8a,
};
std::string srs_ts_stream2string(SrsTsStream stream);

/**
* the ts channel.
*/
struct SrsTsChannel
{
    int pid;
    SrsTsPidApply apply;
    SrsTsStream stream;
    SrsTsMessage* msg;
    SrsTsContext* context;
    // for encoder.
    u_int8_t continuity_counter;

    SrsTsChannel();
    virtual ~SrsTsChannel();
};

/**
* the stream_id of PES payload of ts packet.
* Table 2-18 - Stream_id assignments, hls-mpeg-ts-iso13818-1.pdf, page 52.
*/
enum SrsTsPESStreamId
{
    // program_stream_map
    SrsTsPESStreamIdProgramStreamMap            = 0xbc, // 0b10111100
    // private_stream_1
    SrsTsPESStreamIdPrivateStream1              = 0xbd, // 0b10111101
    // padding_stream
    SrsTsPESStreamIdPaddingStream               = 0xbe, // 0b10111110
    // private_stream_2
    SrsTsPESStreamIdPrivateStream2              = 0xbf, // 0b10111111

    // 110x xxxx
    // ISO/IEC 13818-3 or ISO/IEC 11172-3 or ISO/IEC 13818-7 or ISO/IEC
    // 14496-3 audio stream number x xxxx
    // ((sid >> 5) & 0x07) == SrsTsPESStreamIdAudio
    // @remark, use SrsTsPESStreamIdAudioCommon as actually audio, SrsTsPESStreamIdAudio to check whether audio.
    SrsTsPESStreamIdAudioChecker                = 0x06, // 0b110
        SrsTsPESStreamIdAudioCommon             = 0xc0,

    // 1110 xxxx
    // ITU-T Rec. H.262 | ISO/IEC 13818-2 or ISO/IEC 11172-2 or ISO/IEC
    // 14496-2 video stream number xxxx
    // ((stream_id >> 4) & 0x0f) == SrsTsPESStreamIdVideo
    // @remark, use SrsTsPESStreamIdVideoCommon as actually video, SrsTsPESStreamIdVideo to check whether video.
    SrsTsPESStreamIdVideoChecker                = 0x0e, // 0b1110
        SrsTsPESStreamIdVideoCommon             = 0xe0,

    // ECM_stream
    SrsTsPESStreamIdEcmStream                   = 0xf0, // 0b11110000
    // EMM_stream
    SrsTsPESStreamIdEmmStream                   = 0xf1, // 0b11110001
    // DSMCC_stream
    SrsTsPESStreamIdDsmccStream                 = 0xf2, // 0b11110010
    // 13522_stream
    SrsTsPESStreamId13522Stream                 = 0xf3, // 0b11110011
    // H_222_1_type_A
    SrsTsPESStreamIdH2221TypeA                  = 0xf4, // 0b11110100
    // H_222_1_type_B
    SrsTsPESStreamIdH2221TypeB                  = 0xf5, // 0b11110101
    // H_222_1_type_C
    SrsTsPESStreamIdH2221TypeC                  = 0xf6, // 0b11110110
    // H_222_1_type_D
    SrsTsPESStreamIdH2221TypeD                  = 0xf7, // 0b11110111
    // H_222_1_type_E
    SrsTsPESStreamIdH2221TypeE                  = 0xf8, // 0b11111000
    // ancillary_stream
    SrsTsPESStreamIdAncillaryStream             = 0xf9, // 0b11111001
    // SL_packetized_stream
    SrsTsPESStreamIdSlPacketizedStream          = 0xfa, // 0b11111010
    // FlexMux_stream
    SrsTsPESStreamIdFlexMuxStream               = 0xfb, // 0b11111011
    // reserved data stream
    // 1111 1100 ... 1111 1110
    // program_stream_directory
    SrsTsPESStreamIdProgramStreamDirectory      = 0xff, // 0b11111111
};

/**
* the media audio/video message parsed from PES packet.
*/
class SrsTsMessage
{
public:
    // decoder only,
    // the ts messgae does not use them, 
    // for user to get the channel and packet.
    SrsTsChannel* channel;
    SrsTsPacket* packet;
public:
    // the audio cache buffer start pts, to flush audio if full.
    // @remark the pts is not the adjust one, it's the orignal pts.
    int64_t start_pts;
    // whether this message with pcr info,
    // generally, the video IDR(I frame, the keyframe of h.264) carray the pcr info.
    bool write_pcr;
    // whether got discontinuity ts, for example, sequence header changed.
    bool is_discontinuity;
public:
    // the timestamp in 90khz
    int64_t dts;
    int64_t pts;
    // the id of pes stream to indicates the payload codec.
    // @remark use is_audio() and is_video() to check it, and stream_number() to finger it out.
    SrsTsPESStreamId sid;
    // the size of payload, 0 indicates the length() of payload.
    u_int16_t PES_packet_length;
    // the chunk id.
    u_int8_t continuity_counter;
    // the payload bytes.
    SrsSimpleBuffer* payload;
public:
    SrsTsMessage(SrsTsChannel* c = NULL, SrsTsPacket* p = NULL);
    virtual ~SrsTsMessage();
// decoder
public:
    /**
    * dumps all bytes in stream to ts message.
    */
    virtual int dump(SrsStream* stream, int* pnb_bytes);
    /**
    * whether ts message is completed to reap.
    * @param payload_unit_start_indicator whether new ts message start.
    *       PES_packet_length is 0, the payload_unit_start_indicator=1 to reap ts message.
    *       PES_packet_length > 0, the payload.length() == PES_packet_length to reap ts message.
    * @remark when PES_packet_length>0, the payload_unit_start_indicator should never be 1 when not completed.
    * @remark when fresh, the payload_unit_start_indicator should be 1.
    */
    virtual bool completed(int8_t payload_unit_start_indicator);
    /**
    * whether the message is fresh.
    */
    virtual bool fresh();
public:
    /**
    * whether the sid indicates the elementary stream audio.
    */
    virtual bool is_audio();
    /**
    * whether the sid indicates the elementary stream video.
    */
    virtual bool is_video();
    /**
    * when audio or video, get the stream number which specifies the format of stream.
    * @return the stream number for audio/video; otherwise, -1.
    */
    virtual int stream_number();
public:
    /**
     * detach the ts message,
     * for user maybe need to parse the message by queue.
     * @remark we always use the payload of original message.
     */
    virtual SrsTsMessage* detach();
};

/**
* the ts message handler.
*/
class ISrsTsHandler
{
public:
    ISrsTsHandler();
    virtual ~ISrsTsHandler();
public:
    /**
    * when ts context got message, use handler to process it.
    * @param msg the ts msg, user should never free it.
    * @return an int error code.
    */
    virtual int on_ts_message(SrsTsMessage* msg) = 0;
};

/**
* the context of ts, to decode the ts stream.
*/
class SrsTsContext
{
private:
    // Whether context is ready, failed if try to write data when not ready.
    // When PAT and PMT writen, the context is ready.
    // @see https://github.com/ossrs/srs/issues/834
    bool ready;
// codec
private:
    std::map<int, SrsTsChannel*> pids;
    bool pure_audio;
// encoder
private:
    // when any codec changed, write the PAT/PMT.
    SrsCodecVideo vcodec;
    SrsCodecAudio acodec;
public:
    SrsTsContext();
    virtual ~SrsTsContext();
public:
    /**
     * whether the hls stream is pure audio stream.
     */
    // TODO: FIXME: merge with muxer codec detect.
    virtual bool is_pure_audio();
    /**
     * when PMT table parsed, we know some info about stream.
     */
    virtual void on_pmt_parsed();
    /**
     * reset the context for a new ts segment start.
     */
    virtual void reset();
// codec
public:
    /**
    * get the pid apply, the parsed pid.
    * @return the apply channel; NULL for invalid.
    */
    virtual SrsTsChannel* get(int pid);
    /**
    * set the pid apply, the parsed pid.
    */
    virtual void set(int pid, SrsTsPidApply apply_pid, SrsTsStream stream = SrsTsStreamReserved);
// decode methods
public:
    /**
    * the stream contains only one ts packet.
    * @param handler the ts message handler to process the msg.
    * @remark we will consume all bytes in stream.
    */
    virtual int decode(SrsStream* stream, ISrsTsHandler* handler);
// encode methods
public:
    /**
    * write the PES packet, the video/audio stream.
    * @param msg the video/audio msg to write to ts.
    * @param vc the video codec, write the PAT/PMT table when changed.
    * @param ac the audio codec, write the PAT/PMT table when changed.
    */
    virtual int encode(SrsFileWriter* writer, SrsTsMessage* msg, SrsCodecVideo vc, SrsCodecAudio ac);
private:
    virtual int encode_pat_pmt(SrsFileWriter* writer, int16_t vpid, SrsTsStream vs, int16_t apid, SrsTsStream as);
    virtual int encode_pes(SrsFileWriter* writer, SrsTsMessage* msg, int16_t pid, SrsTsStream sid, bool pure_audio);
};

/**
* the packet in ts stream,
* 2.4.3.2 Transport Stream packet layer, hls-mpeg-ts-iso13818-1.pdf, page 36
* Transport Stream packets shall be 188 bytes long.
*/
class SrsTsPacket
{
public:
    // 1B
    /**
    * The sync_byte is a fixed 8-bit field whose value is '0100 0111' (0x47). Sync_byte emulation in the choice of
    * values for other regularly occurring fields, such as PID, should be avoided.
    */
    int8_t sync_byte; //8bits

    // 2B
    /**
    * The transport_error_indicator is a 1-bit flag. When set to '1' it indicates that at least
    * 1 uncorrectable bit error exists in the associated Transport Stream packet. This bit may be set to '1' by entities external to
    * the transport layer. When set to '1' this bit shall not be reset to '0' unless the bit value(s) in error have been corrected.
    */
    int8_t transport_error_indicator; //1bit
    /**
    * The payload_unit_start_indicator is a 1-bit flag which has normative meaning for
    * Transport Stream packets that carry PES packets (refer to 2.4.3.6) or PSI data (refer to 2.4.4).
    * 
    * When the payload of the Transport Stream packet contains PES packet data, the payload_unit_start_indicator has the
    * following significance: a '1' indicates that the payload of this Transport Stream packet will commence(start) with the first byte
    * of a PES packet and a '0' indicates no PES packet shall start in this Transport Stream packet. If the
    * payload_unit_start_indicator is set to '1', then one and only one PES packet starts in this Transport Stream packet. This
    * also applies to private streams of stream_type 6 (refer to Table 2-29).
    *
    * When the payload of the Transport Stream packet contains PSI data, the payload_unit_start_indicator has the following
    * significance: if the Transport Stream packet carries the first byte of a PSI section, the payload_unit_start_indicator value
    * shall be '1', indicating that the first byte of the payload of this Transport Stream packet carries the pointer_field. If the
    * Transport Stream packet does not carry the first byte of a PSI section, the payload_unit_start_indicator value shall be '0',
    * indicating that there is no pointer_field in the payload. Refer to 2.4.4.1 and 2.4.4.2. This also applies to private streams of
    * stream_type 5 (refer to Table 2-29).
    * 
    * For null packets the payload_unit_start_indicator shall be set to '0'.
    * 
    * The meaning of this bit for Transport Stream packets carrying only private data is not defined in this Specification.
    */
    int8_t payload_unit_start_indicator; //1bit
    /**
    * The transport_priority is a 1-bit indicator. When set to '1' it indicates that the associated packet is
    * of greater priority than other packets having the same PID which do not have the bit set to '1'. The transport mechanism
    * can use this to prioritize its data within an elementary stream. Depending on the application the transport_priority field
    * may be coded regardless of the PID or within one PID only. This field may be changed by channel specific encoders or
    * decoders.
    */
    int8_t transport_priority; //1bit
    /**
    * The PID is a 13-bit field, indicating the type of the data stored in the packet payload. PID value 0x0000 is
    * reserved for the Program Association Table (see Table 2-25). PID value 0x0001 is reserved for the Conditional Access
    * Table (see Table 2-27). PID values 0x0002 - 0x000F are reserved. PID value 0x1FFF is reserved for null packets (see
    * Table 2-3).
    */
    SrsTsPid pid; //13bits

    // 1B
    /**
    * This 2-bit field indicates the scrambling mode of the Transport Stream packet payload.
    * The Transport Stream packet header, and the adaptation field when present, shall not be scrambled. In the case of a null
    * packet the value of the transport_scrambling_control field shall be set to '00' (see Table 2-4).
    */
    SrsTsScrambled transport_scrambling_control; //2bits
    /**
    * This 2-bit field indicates whether this Transport Stream packet header is followed by an
    * adaptation field and/or payload (see Table 2-5).
    *
    * ITU-T Rec. H.222.0 | ISO/IEC 13818-1 decoders shall discard Transport Stream packets with the
    * adaptation_field_control field set to a value of '00'. In the case of a null packet the value of the adaptation_field_control
    * shall be set to '01'.
    */
    SrsTsAdaptationFieldType adaption_field_control; //2bits
    /**
    * The continuity_counter is a 4-bit field incrementing with each Transport Stream packet with the
    * same PID. The continuity_counter wraps around to 0 after its maximum value. The continuity_counter shall not be
    * incremented when the adaptation_field_control of the packet equals '00'(reseverd) or '10'(adaptation field only).
    * 
    * In Transport Streams, duplicate packets may be sent as two, and only two, consecutive Transport Stream packets of the
    * same PID. The duplicate packets shall have the same continuity_counter value as the original packet and the
    * adaptation_field_control field shall be equal to '01'(payload only) or '11'(both). In duplicate packets each byte of the original packet shall be
    * duplicated, with the exception that in the program clock reference fields, if present, a valid value shall be encoded.
    *
    * The continuity_counter in a particular Transport Stream packet is continuous when it differs by a positive value of one
    * from the continuity_counter value in the previous Transport Stream packet of the same PID, or when either of the nonincrementing
    * conditions (adaptation_field_control set to '00' or '10', or duplicate packets as described above) are met.
    * The continuity counter may be discontinuous when the discontinuity_indicator is set to '1' (refer to 2.4.3.4). In the case of
    * a null packet the value of the continuity_counter is undefined.
    */
    u_int8_t continuity_counter; //4bits
private:
    SrsTsAdaptationField* adaptation_field;
    SrsTsPayload* payload;
public:
    SrsTsContext* context;
public:
    SrsTsPacket(SrsTsContext* c);
    virtual ~SrsTsPacket();
public:
    virtual int decode(SrsStream* stream, SrsTsMessage** ppmsg);
public:
    virtual int size();
    virtual int encode(SrsStream* stream);
    virtual void padding(int nb_stuffings);
public:
    static SrsTsPacket* create_pat(SrsTsContext* context, 
        int16_t pmt_number, int16_t pmt_pid
    );
    static SrsTsPacket* create_pmt(SrsTsContext* context, 
        int16_t pmt_number, int16_t pmt_pid, int16_t vpid, SrsTsStream vs, 
        int16_t apid, SrsTsStream as
    );
    static SrsTsPacket* create_pes_first(SrsTsContext* context, 
        int16_t pid, SrsTsPESStreamId sid, u_int8_t continuity_counter, bool discontinuity, 
        int64_t pcr, int64_t dts, int64_t pts, int size
    );
    static SrsTsPacket* create_pes_continue(SrsTsContext* context, 
        int16_t pid, SrsTsPESStreamId sid, u_int8_t continuity_counter
    );
};

/**
* the adaption field of ts packet.
* 2.4.3.5 Semantic definition of fields in adaptation field, hls-mpeg-ts-iso13818-1.pdf, page 39
* Table 2-6 - Transport Stream adaptation field, hls-mpeg-ts-iso13818-1.pdf, page 40
*/
class SrsTsAdaptationField
{
public:
    // 1B
    /**
    * The adaptation_field_length is an 8-bit field specifying the number of bytes in the
    * adaptation_field immediately following the adaptation_field_length. The value 0 is for inserting a single stuffing byte in
    * a Transport Stream packet. When the adaptation_field_control value is '11', the value of the adaptation_field_length shall
    * be in the range 0 to 182. When the adaptation_field_control value is '10', the value of the adaptation_field_length shall
    * be 183. For Transport Stream packets carrying PES packets, stuffing is needed when there is insufficient PES packet data
    * to completely fill the Transport Stream packet payload bytes. Stuffing is accomplished by defining an adaptation field
    * longer than the sum of the lengths of the data elements in it, so that the payload bytes remaining after the adaptation field
    * exactly accommodates the available PES packet data. The extra space in the adaptation field is filled with stuffing bytes.
    *
    * This is the only method of stuffing allowed for Transport Stream packets carrying PES packets. For Transport Stream
    * packets carrying PSI, an alternative stuffing method is described in 2.4.4.
    */
    u_int8_t adaption_field_length; //8bits
    // 1B
    /**
    * This is a 1-bit field which when set to '1' indicates that the discontinuity state is true for the
    * current Transport Stream packet. When the discontinuity_indicator is set to '0' or is not present, the discontinuity state is
    * false. The discontinuity indicator is used to indicate two types of discontinuities, system time-base discontinuities and
    * continuity_counter discontinuities.
    * 
    * A system time-base discontinuity is indicated by the use of the discontinuity_indicator in Transport Stream packets of a
    * PID designated as a PCR_PID (refer to 2.4.4.9). When the discontinuity state is true for a Transport Stream packet of a
    * PID designated as a PCR_PID, the next PCR in a Transport Stream packet with that same PID represents a sample of a
    * new system time clock for the associated program. The system time-base discontinuity point is defined to be the instant
    * in time when the first byte of a packet containing a PCR of a new system time-base arrives at the input of the T-STD.
    * The discontinuity_indicator shall be set to '1' in the packet in which the system time-base discontinuity occurs. The
    * discontinuity_indicator bit may also be set to '1' in Transport Stream packets of the same PCR_PID prior to the packet
    * which contains the new system time-base PCR. In this case, once the discontinuity_indicator has been set to '1', it shall
    * continue to be set to '1' in all Transport Stream packets of the same PCR_PID up to and including the Transport Stream
    * packet which contains the first PCR of the new system time-base. After the occurrence of a system time-base
    * discontinuity, no fewer than two PCRs for the new system time-base shall be received before another system time-base
    * discontinuity can occur. Further, except when trick mode status is true, data from no more than two system time-bases
    * shall be present in the set of T-STD buffers for one program at any time.
    *
    * Prior to the occurrence of a system time-base discontinuity, the first byte of a Transport Stream packet which contains a
    * PTS or DTS which refers to the new system time-base shall not arrive at the input of the T-STD. After the occurrence of
    * a system time-base discontinuity, the first byte of a Transport Stream packet which contains a PTS or DTS which refers
    * to the previous system time-base shall not arrive at the input of the T-STD.
    *
    * A continuity_counter discontinuity is indicated by the use of the discontinuity_indicator in any Transport Stream packet.
    * When the discontinuity state is true in any Transport Stream packet of a PID not designated as a PCR_PID, the
    * continuity_counter in that packet may be discontinuous with respect to the previous Transport Stream packet of the same
    * PID. When the discontinuity state is true in a Transport Stream packet of a PID that is designated as a PCR_PID, the
    * continuity_counter may only be discontinuous in the packet in which a system time-base discontinuity occurs. A
    * continuity counter discontinuity point occurs when the discontinuity state is true in a Transport Stream packet and the
    * continuity_counter in the same packet is discontinuous with respect to the previous Transport Stream packet of the same
    * PID. A continuity counter discontinuity point shall occur at most one time from the initiation of the discontinuity state
    * until the conclusion of the discontinuity state. Furthermore, for all PIDs that are not designated as PCR_PIDs, when the
    * discontinuity_indicator is set to '1' in a packet of a specific PID, the discontinuity_indicator may be set to '1' in the next
    * Transport Stream packet of that same PID, but shall not be set to '1' in three consecutive Transport Stream packet of that
    * same PID.
    *
    * For the purpose of this clause, an elementary stream access point is defined as follows:
    *       Video - The first byte of a video sequence header.
    *       Audio - The first byte of an audio frame.
    *
    * After a continuity counter discontinuity in a Transport packet which is designated as containing elementary stream data,
    * the first byte of elementary stream data in a Transport Stream packet of the same PID shall be the first byte of an
    * elementary stream access point or in the case of video, the first byte of an elementary stream access point or a
    * sequence_end_code followed by an access point. Each Transport Stream packet which contains elementary stream data
    * with a PID not designated as a PCR_PID, and in which a continuity counter discontinuity point occurs, and in which a
    * PTS or DTS occurs, shall arrive at the input of the T-STD after the system time-base discontinuity for the associated
    * program occurs. In the case where the discontinuity state is true, if two consecutive Transport Stream packets of the same
    * PID occur which have the same continuity_counter value and have adaptation_field_control values set to '01' or '11', the
    * second packet may be discarded. A Transport Stream shall not be constructed in such a way that discarding such a packet
    * will cause the loss of PES packet payload data or PSI data.
    *
    * After the occurrence of a discontinuity_indicator set to '1' in a Transport Stream packet which contains PSI information,
    * a single discontinuity in the version_number of PSI sections may occur. At the occurrence of such a discontinuity, a
    * version of the TS_program_map_sections of the appropriate program shall be sent with section_length = = 13 and the
    * current_next_indicator = = 1, such that there are no program_descriptors and no elementary streams described. This shall
    * then be followed by a version of the TS_program_map_section for each affected program with the version_number
    * incremented by one and the current_next_indicator = = 1, containing a complete program definition. This indicates a
    * version change in PSI data.
    */
    int8_t discontinuity_indicator; //1bit
    /**
    * The random_access_indicator is a 1-bit field that indicates that the current Transport
    * Stream packet, and possibly subsequent Transport Stream packets with the same PID, contain some information to aid
    * random access at this point. Specifically, when the bit is set to '1', the next PES packet to start in the payload of Transport
    * Stream packets with the current PID shall contain the first byte of a video sequence header if the PES stream type (refer
    * to Table 2-29) is 1 or 2, or shall contain the first byte of an audio frame if the PES stream type is 3 or 4. In addition, in
    * the case of video, a presentation timestamp shall be present in the PES packet containing the first picture following the
    * sequence header. In the case of audio, the presentation timestamp shall be present in the PES packet containing the first
    * byte of the audio frame. In the PCR_PID the random_access_indicator may only be set to '1' in Transport Stream packet
    * containing the PCR fields.
    */
    int8_t random_access_indicator; //1bit
    /**
    * The elementary_stream_priority_indicator is a 1-bit field. It indicates, among
    * packets with the same PID, the priority of the elementary stream data carried within the payload of this Transport Stream
    * packet. A '1' indicates that the payload has a higher priority than the payloads of other Transport Stream packets. In the
    * case of video, this field may be set to '1' only if the payload contains one or more bytes from an intra-coded slice. A
    * value of '0' indicates that the payload has the same priority as all other packets which do not have this bit set to '1'.
    */
    int8_t elementary_stream_priority_indicator; //1bit
    /**
    * The PCR_flag is a 1-bit flag. A value of '1' indicates that the adaptation_field contains a PCR field coded in
    * two parts. A value of '0' indicates that the adaptation field does not contain any PCR field.
    */
    int8_t PCR_flag; //1bit
    /**
    * The OPCR_flag is a 1-bit flag. A value of '1' indicates that the adaptation_field contains an OPCR field
    * coded in two parts. A value of '0' indicates that the adaptation field does not contain any OPCR field.
    */
    int8_t OPCR_flag; //1bit
    /**
    * The splicing_point_flag is a 1-bit flag. When set to '1', it indicates that a splice_countdown field
    * shall be present in the associated adaptation field, specifying the occurrence of a splicing point. A value of '0' indicates
    * that a splice_countdown field is not present in the adaptation field.
    */
    int8_t splicing_point_flag; //1bit
    /**
    * The transport_private_data_flag is a 1-bit flag. A value of '1' indicates that the
    * adaptation field contains one or more private_data bytes. A value of '0' indicates the adaptation field does not contain any
    * private_data bytes.
    */
    int8_t transport_private_data_flag; //1bit
    /**
    * The adaptation_field_extension_flag is a 1-bit field which when set to '1' indicates
    * the presence of an adaptation field extension. A value of '0' indicates that an adaptation field extension is not present in
    * the adaptation field.
    */
    int8_t adaptation_field_extension_flag; //1bit
    
    // if PCR_flag, 6B
    /**
    * The program_clock_reference (PCR) is a
    * 42-bit field coded in two parts. The first part, program_clock_reference_base, is a 33-bit field whose value is given by
    * PCR_base(i), as given in equation 2-2. The second part, program_clock_reference_extension, is a 9-bit field whose value
    * is given by PCR_ext(i), as given in equation 2-3. The PCR indicates the intended time of arrival of the byte containing
    * the last bit of the program_clock_reference_base at the input of the system target decoder.
    */
    int64_t program_clock_reference_base; //33bits
    /**
    * 6bits reserved, must be '1'
    */
    int8_t const1_value0; // 6bits
    int16_t program_clock_reference_extension; //9bits
    
    // if OPCR_flag, 6B
    /**
    * The optional original
    * program reference (OPCR) is a 42-bit field coded in two parts. These two parts, the base and the extension, are coded
    * identically to the two corresponding parts of the PCR field. The presence of the OPCR is indicated by the OPCR_flag.
    * The OPCR field shall be coded only in Transport Stream packets in which the PCR field is present. OPCRs are permitted
    * in both single program and multiple program Transport Streams.
    *
    * OPCR assists in the reconstruction of a single program Transport Stream from another Transport Stream. When
    * reconstructing the original single program Transport Stream, the OPCR may be copied to the PCR field. The resulting
    * PCR value is valid only if the original single program Transport Stream is reconstructed exactly in its entirety. This
    * would include at least any PSI and private data packets which were present in the original Transport Stream and would
    * possibly require other private arrangements. It also means that the OPCR must be an identical copy of its associated PCR
    * in the original single program Transport Stream.
    */
    int64_t original_program_clock_reference_base; //33bits
    /**
    * 6bits reserved, must be '1'
    */
    int8_t const1_value2; // 6bits
    int16_t original_program_clock_reference_extension; //9bits
    
    // if splicing_point_flag, 1B
    /**
    * The splice_countdown is an 8-bit field, representing a value which may be positive or negative. A
    * positive value specifies the remaining number of Transport Stream packets, of the same PID, following the associated
    * Transport Stream packet until a splicing point is reached. Duplicate Transport Stream packets and Transport Stream
    * packets which only contain adaptation fields are excluded. The splicing point is located immediately after the last byte of
    * the Transport Stream packet in which the associated splice_countdown field reaches zero. In the Transport Stream packet
    * where the splice_countdown reaches zero, the last data byte of the Transport Stream packet payload shall be the last byte
    * of a coded audio frame or a coded picture. In the case of video, the corresponding access unit may or may not be
    * terminated by a sequence_end_code. Transport Stream packets with the same PID, which follow, may contain data from
    * a different elementary stream of the same type.
    *
    * The payload of the next Transport Stream packet of the same PID (duplicate packets and packets without payload being
    * excluded) shall commence with the first byte of a PES packet.In the case of audio, the PES packet payload shall
    * commence with an access point. In the case of video, the PES packet payload shall commence with an access point, or
    * with a sequence_end_code, followed by an access point. Thus, the previous coded audio frame or coded picture aligns
    * with the packet boundary, or is padded to make this so. Subsequent to the splicing point, the countdown field may also
    * be present. When the splice_countdown is a negative number whose value is minus n(-n), it indicates that the associated
    * Transport Stream packet is the n-th packet following the splicing point (duplicate packets and packets without payload
    * being excluded).
    * 
    * For the purposes of this subclause, an access point is defined as follows:
    *       Video - The first byte of a video_sequence_header.
    *       Audio - The first byte of an audio frame.
    */
    int8_t splice_countdown; //8bits
    
    // if transport_private_data_flag, 1+p[0] B
    /**
    * The transport_private_data_length is an 8-bit field specifying the number of
    * private_data bytes immediately following the transport private_data_length field. The number of private_data bytes shall
    * not be such that private data extends beyond the adaptation field.
    */
    u_int8_t transport_private_data_length; //8bits
    char* transport_private_data; //[transport_private_data_length]bytes
    
    // if adaptation_field_extension_flag, 2+x B
    /**
    * The adaptation_field_extension_length is an 8-bit field. It indicates the number of
    * bytes of the extended adaptation field data immediately following this field, including reserved bytes if present.
    */
    u_int8_t adaptation_field_extension_length; //8bits
    /**
    * This is a 1-bit field which when set to '1' indicates the presence of the ltw_offset
    * field.
    */
    int8_t ltw_flag; //1bit
    /**
    * This is a 1-bit field which when set to '1' indicates the presence of the piecewise_rate field.
    */
    int8_t piecewise_rate_flag; //1bit
    /**
    * This is a 1-bit flag which when set to '1' indicates that the splice_type and DTS_next_AU fields
    * are present. A value of '0' indicates that neither splice_type nor DTS_next_AU fields are present. This field shall not be
    * set to '1' in Transport Stream packets in which the splicing_point_flag is not set to '1'. Once it is set to '1' in a Transport
    * Stream packet in which the splice_countdown is positive, it shall be set to '1' in all the subsequent Transport Stream
    * packets of the same PID that have the splicing_point_flag set to '1', until the packet in which the splice_countdown
    * reaches zero (including this packet). When this flag is set, if the elementary stream carried in this PID is an audio stream,
    * the splice_type field shall be set to '0000'. If the elementary stream carried in this PID is a video stream, it shall fulfil the
    * constraints indicated by the splice_type value.
    */
    int8_t seamless_splice_flag; //1bit
    /**
    * reserved 5bits, must be '1'
    */
    int8_t const1_value1; //5bits
    // if ltw_flag, 2B
    /**
    * (legal time window_valid_flag) - This is a 1-bit field which when set to '1' indicates that the value of the
    * ltw_offset shall be valid. A value of '0' indicates that the value in the ltw_offset field is undefined.
    */
    int8_t ltw_valid_flag; //1bit
    /**
    * (legal time window offset) - This is a 15-bit field, the value of which is defined only if the ltw_valid flag has
    * a value of '1'. When defined, the legal time window offset is in units of (300/fs) seconds, where fs is the system clock
    * frequency of the program that this PID belongs to, and fulfils:
    *       offset = t1(i) - t(i)
    *       ltw_offset = offset//1
    * where i is the index of the first byte of this Transport Stream packet, offset is the value encoded in this field, t(i) is the
    * arrival time of byte i in the T-STD, and t1(i) is the upper bound in time of a time interval called the Legal Time Window
    * which is associated with this Transport Stream packet.
    */
    int16_t ltw_offset; //15bits
    // if piecewise_rate_flag, 3B
    //2bits reserved
    /**
    * The meaning of this 22-bit field is only defined when both the ltw_flag and the ltw_valid_flag are set
    * to '1'. When defined, it is a positive integer specifying a hypothetical bitrate R which is used to define the end times of
    * the Legal Time Windows of Transport Stream packets of the same PID that follow this packet but do not include the
    * legal_time_window_offset field.
    */
    int32_t piecewise_rate; //22bits
    // if seamless_splice_flag, 5B
    /**
    * This is a 4-bit field. From the first occurrence of this field onwards, it shall have the same value in all the
    * subsequent Transport Stream packets of the same PID in which it is present, until the packet in which the
    * splice_countdown reaches zero (including this packet). If the elementary stream carried in that PID is an audio stream,
    * this field shall have the value '0000'. If the elementary stream carried in that PID is a video stream, this field indicates the
    * conditions that shall be respected by this elementary stream for splicing purposes. These conditions are defined as a
    * function of profile, level and splice_type in Table 2-7 through Table 2-16.
    */
    int8_t splice_type; //4bits
    /**
    * (decoding time stamp next access unit) - This is a 33-bit field, coded in three parts. In the case of
    * continuous and periodic decoding through this splicing point it indicates the decoding time of the first access unit
    * following the splicing point. This decoding time is expressed in the time base which is valid in the Transport Stream
    * packet in which the splice_countdown reaches zero. From the first occurrence of this field onwards, it shall have the
    * same value in all the subsequent Transport Stream packets of the same PID in which it is present, until the packet in
    * which the splice_countdown reaches zero (including this packet).
    */
    int8_t DTS_next_AU0; //3bits
    int8_t marker_bit0; //1bit
    int16_t DTS_next_AU1; //15bits
    int8_t marker_bit1; //1bit
    int16_t DTS_next_AU2; //15bits
    int8_t marker_bit2; //1bit
    // left bytes.
    /**
    * This is a fixed 8-bit value equal to '1111 1111' that can be inserted by the encoder. It is discarded by the
    * decoder.
    */
    int nb_af_ext_reserved;
    
    // left bytes.
    /**
    * This is a fixed 8-bit value equal to '1111 1111' that can be inserted by the encoder. It is discarded by the
    * decoder.
    */
    int nb_af_reserved;
private:
    SrsTsPacket* packet;
public:
    SrsTsAdaptationField(SrsTsPacket* pkt);
    virtual ~SrsTsAdaptationField();
public:
    virtual int decode(SrsStream* stream);
public:
    virtual int size();
    virtual int encode(SrsStream* stream);
};

/**
* 2.4.4.4 Table_id assignments, hls-mpeg-ts-iso13818-1.pdf, page 62
* The table_id field identifies the contents of a Transport Stream PSI section as shown in Table 2-26.
*/
enum SrsTsPsiId
{
    // program_association_section
    SrsTsPsiIdPas               = 0x00,
    // conditional_access_section (CA_section)
    SrsTsPsiIdCas               = 0x01,
    // TS_program_map_section
    SrsTsPsiIdPms               = 0x02,
    // TS_description_section
    SrsTsPsiIdDs                = 0x03,
    // ISO_IEC_14496_scene_description_section
    SrsTsPsiIdSds               = 0x04,
    // ISO_IEC_14496_object_descriptor_section
    SrsTsPsiIdOds               = 0x05,
    // ITU-T Rec. H.222.0 | ISO/IEC 13818-1 reserved
    SrsTsPsiIdIso138181Start    = 0x06,
    SrsTsPsiIdIso138181End      = 0x37,
    // Defined in ISO/IEC 13818-6
    SrsTsPsiIdIso138186Start    = 0x38,
    SrsTsPsiIdIso138186End      = 0x3F,
    // User private
    SrsTsPsiIdUserStart         = 0x40,
    SrsTsPsiIdUserEnd           = 0xFE,
    // forbidden
    SrsTsPsiIdForbidden         = 0xFF,
};

/**
* the payload of ts packet, can be PES or PSI payload.
*/
class SrsTsPayload
{
protected:
    SrsTsPacket* packet;
public:
    SrsTsPayload(SrsTsPacket* p);
    virtual ~SrsTsPayload();
public:
    virtual int decode(SrsStream* stream, SrsTsMessage** ppmsg) = 0;
public:
    virtual int size() = 0;
    virtual int encode(SrsStream* stream) = 0;
};

/**
* the PES payload of ts packet.
* 2.4.3.6 PES packet, hls-mpeg-ts-iso13818-1.pdf, page 49
*/
class SrsTsPayloadPES : public SrsTsPayload
{
public:
    // 3B
    /**
    * The packet_start_code_prefix is a 24-bit code. Together with the stream_id that follows it
    * constitutes a packet start code that identifies the beginning of a packet. The packet_start_code_prefix is the bit string
    * '0000 0000 0000 0000 0000 0001' (0x000001).
    */
    int32_t packet_start_code_prefix; //24bits
    // 1B
    /**
    * In Program Streams, the stream_id specifies the type and number of the elementary stream as defined by the
    * stream_id Table 2-18. In Transport Streams, the stream_id may be set to any valid value which correctly describes the
    * elementary stream type as defined in Table 2-18. In Transport Streams, the elementary stream type is specified in the
    * Program Specific Information as specified in 2.4.4.
    */
    // @see SrsTsPESStreamId, value can be SrsTsPESStreamIdAudioCommon or SrsTsPESStreamIdVideoCommon.
    u_int8_t stream_id; //8bits
    // 2B
    /**
    * A 16-bit field specifying the number of bytes in the PES packet following the last byte of the
    * field. A value of 0 indicates that the PES packet length is neither specified nor bounded and is allowed only in
    * PES packets whose payload consists of bytes from a video elementary stream contained in Transport Stream packets.
    */
    u_int16_t PES_packet_length; //16bits

    // 1B
    /**
    * 2bits const '10'
    */
    int8_t const2bits; //2bits
    /**
    * The 2-bit PES_scrambling_control field indicates the scrambling mode of the PES packet
    * payload. When scrambling is performed at the PES level, the PES packet header, including the optional fields when
    * present, shall not be scrambled (see Table 2-19).
    */
    int8_t PES_scrambling_control; //2bits
    /**
    * This is a 1-bit field indicating the priority of the payload in this PES packet. A '1' indicates a higher
    * priority of the payload of the PES packet payload than a PES packet payload with this field set to '0'. A multiplexor can
    * use the PES_priority bit to prioritize its data within an elementary stream. This field shall not be changed by the transport
    * mechanism.
    */
    int8_t PES_priority; //1bit
    /**
    * This is a 1-bit flag. When set to a value of '1' it indicates that the PES packet header is
    * immediately followed by the video start code or audio syncword indicated in the data_stream_alignment_descriptor
    * in 2.6.10 if this descriptor is present. If set to a value of '1' and the descriptor is not present, alignment as indicated in
    * alignment_type '01' in Table 2-47 and Table 2-48 is required. When set to a value of '0' it is not defined whether any such
    * alignment occurs or not.
    */
    int8_t data_alignment_indicator; //1bit
    /**
    * This is a 1-bit field. When set to '1' it indicates that the material of the associated PES packet payload is
    * protected by copyright. When set to '0' it is not defined whether the material is protected by copyright. A copyright
    * descriptor described in 2.6.24 is associated with the elementary stream which contains this PES packet and the copyright
    * flag is set to '1' if the descriptor applies to the material contained in this PES packet
    */
    int8_t copyright; //1bit
    /**
    * This is a 1-bit field. When set to '1' the contents of the associated PES packet payload is an original.
    * When set to '0' it indicates that the contents of the associated PES packet payload is a copy.
    */
    int8_t original_or_copy; //1bit

    // 1B
    /**
    * This is a 2-bit field. When the PTS_DTS_flags field is set to '10', the PTS fields shall be present in
    * the PES packet header. When the PTS_DTS_flags field is set to '11', both the PTS fields and DTS fields shall be present
    * in the PES packet header. When the PTS_DTS_flags field is set to '00' no PTS or DTS fields shall be present in the PES
    * packet header. The value '01' is forbidden.
    */
    int8_t PTS_DTS_flags; //2bits
    /**
    * A 1-bit flag, which when set to '1' indicates that ESCR base and extension fields are present in the PES
    * packet header. When set to '0' it indicates that no ESCR fields are present.
    */
    int8_t ESCR_flag; //1bit
    /**
    * A 1-bit flag, which when set to '1' indicates that the ES_rate field is present in the PES packet header.
    * When set to '0' it indicates that no ES_rate field is present.
    */
    int8_t ES_rate_flag; //1bit
    /**
    * A 1-bit flag, which when set to '1' it indicates the presence of an 8-bit trick mode field. When
    * set to '0' it indicates that this field is not present.
    */
    int8_t DSM_trick_mode_flag; //1bit
    /**
    * A 1-bit flag, which when set to '1' indicates the presence of the additional_copy_info field.
    * When set to '0' it indicates that this field is not present.
    */
    int8_t additional_copy_info_flag; //1bit
    /**
    * A 1-bit flag, which when set to '1' indicates that a CRC field is present in the PES packet. When set to
    * '0' it indicates that this field is not present.
    */
    int8_t PES_CRC_flag; //1bit
    /**
    * A 1-bit flag, which when set to '1' indicates that an extension field exists in this PES packet
    * header. When set to '0' it indicates that this field is not present.
    */
    int8_t PES_extension_flag; //1bit

    // 1B
    /**
    * An 8-bit field specifying the total number of bytes occupied by the optional fields and any
    * stuffing bytes contained in this PES packet header. The presence of optional fields is indicated in the byte that precedes
    * the PES_header_data_length field.
    */
    u_int8_t PES_header_data_length; //8bits

    // 5B
    /**
    * Presentation times shall be related to decoding times as follows: The PTS is a 33-bit
    * number coded in three separate fields. It indicates the time of presentation, tp n (k), in the system target decoder of a
    * presentation unit k of elementary stream n. The value of PTS is specified in units of the period of the system clock
    * frequency divided by 300 (yielding 90 kHz). The presentation time is derived from the PTS according to equation 2-11
    * below. Refer to 2.7.4 for constraints on the frequency of coding presentation timestamps.
    */
    // ===========1B
    // 4bits const
    // 3bits PTS [32..30]
    // 1bit const '1'
    // ===========2B
    // 15bits PTS [29..15]
    // 1bit const '1'
    // ===========2B
    // 15bits PTS [14..0]
    // 1bit const '1'
    int64_t pts; // 33bits

    // 5B
    /**
    * The DTS is a 33-bit number coded in three separate fields. It indicates the decoding time,
    * td n (j), in the system target decoder of an access unit j of elementary stream n. The value of DTS is specified in units of
    * the period of the system clock frequency divided by 300 (yielding 90 kHz).
    */
    // ===========1B
    // 4bits const
    // 3bits DTS [32..30]
    // 1bit const '1'
    // ===========2B
    // 15bits DTS [29..15]
    // 1bit const '1'
    // ===========2B
    // 15bits DTS [14..0]
    // 1bit const '1'
    int64_t dts; // 33bits

    // 6B
    /**
    * The elementary stream clock reference is a 42-bit field coded in two parts. The first
    * part, ESCR_base, is a 33-bit field whose value is given by ESCR_base(i), as given in equation 2-14. The second part,
    * ESCR_ext, is a 9-bit field whose value is given by ESCR_ext(i), as given in equation 2-15. The ESCR field indicates the
    * intended time of arrival of the byte containing the last bit of the ESCR_base at the input of the PES-STD for PES streams
    * (refer to 2.5.2.4).
    */
    // 2bits reserved
    // 3bits ESCR_base[32..30]
    // 1bit const '1'
    // 15bits ESCR_base[29..15]
    // 1bit const '1'
    // 15bits ESCR_base[14..0]
    // 1bit const '1'
    // 9bits ESCR_extension
    // 1bit const '1'
    int64_t ESCR_base; //33bits
    int16_t ESCR_extension; //9bits

    // 3B
    /**
    * The ES_rate field is a 22-bit unsigned integer specifying the rate at which the
    * system target decoder receives bytes of the PES packet in the case of a PES stream. The ES_rate is valid in the PES
    * packet in which it is included and in subsequent PES packets of the same PES stream until a new ES_rate field is
    * encountered. The value of the ES_rate is measured in units of 50 bytes/second. The value 0 is forbidden. The value of the
    * ES_rate is used to define the time of arrival of bytes at the input of a P-STD for PES streams defined in 2.5.2.4. The
    * value encoded in the ES_rate field may vary from PES_packet to PES_packet.
    */
    // 1bit const '1'
    // 22bits ES_rate
    // 1bit const '1'
    int32_t ES_rate; //22bits

    // 1B
    /**
    * A 3-bit field that indicates which trick mode is applied to the associated video stream. In cases of
    * other types of elementary streams, the meanings of this field and those defined by the following five bits are undefined.
    * For the definition of trick_mode status, refer to the trick mode section of 2.4.2.3.
    */
    int8_t trick_mode_control; //3bits
    int8_t trick_mode_value; //5bits

    // 1B
    // 1bit const '1'
    /**
    * This 7-bit field contains private data relating to copyright information.
    */
    int8_t additional_copy_info; //7bits

    // 2B
    /**
    * The previous_PES_packet_CRC is a 16-bit field that contains the CRC value that yields
    * a zero output of the 16 registers in the decoder similar to the one defined in Annex A,
    */
    int16_t previous_PES_packet_CRC; //16bits

    // 1B
    /**
    * A 1-bit flag which when set to '1' indicates that the PES packet header contains private data.
    * When set to a value of '0' it indicates that private data is not present in the PES header.
    */
    int8_t PES_private_data_flag; //1bit
    /**
    * A 1-bit flag which when set to '1' indicates that an ISO/IEC 11172-1 pack header or a
    * Program Stream pack header is stored in this PES packet header. If this field is in a PES packet that is contained in a
    * Program Stream, then this field shall be set to '0'. In a Transport Stream, when set to the value '0' it indicates that no pack
    * header is present in the PES header.
    */
    int8_t pack_header_field_flag; //1bit
    /**
    * A 1-bit flag which when set to '1' indicates that the
    * program_packet_sequence_counter, MPEG1_MPEG2_identifier, and original_stuff_length fields are present in this
    * PES packet. When set to a value of '0' it indicates that these fields are not present in the PES header.
    */
    int8_t program_packet_sequence_counter_flag; //1bit
    /**
    * A 1-bit flag which when set to '1' indicates that the P-STD_buffer_scale and P-STD_buffer_size
    * are present in the PES packet header. When set to a value of '0' it indicates that these fields are not present in the
    * PES header.
    */
    int8_t P_STD_buffer_flag; //1bit
    /**
    * reverved value, must be '1'
    */
    int8_t const1_value0; //3bits
    /**
    * A 1-bit field which when set to '1' indicates the presence of the PES_extension_field_length
    * field and associated fields. When set to a value of '0' this indicates that the PES_extension_field_length field and any
    * associated fields are not present.
    */
    int8_t PES_extension_flag_2; //1bit

    // 16B
    /**
    * This is a 16-byte field which contains private data. This data, combined with the fields before and
    * after, shall not emulate the packet_start_code_prefix (0x000001).
    */
    char* PES_private_data; //128bits

    // (1+x)B
    /**
    * This is an 8-bit field which indicates the length, in bytes, of the pack_header_field().
    */
    u_int8_t pack_field_length; //8bits
    char* pack_field; //[pack_field_length] bytes

    // 2B
    // 1bit const '1'
    /**
    * The program_packet_sequence_counter field is a 7-bit field. It is an optional
    * counter that increments with each successive PES packet from a Program Stream or from an ISO/IEC 11172-1 Stream or
    * the PES packets associated with a single program definition in a Transport Stream, providing functionality similar to a
    * continuity counter (refer to 2.4.3.2). This allows an application to retrieve the original PES packet sequence of a Program
    * Stream or the original packet sequence of the original ISO/IEC 11172-1 stream. The counter will wrap around to 0 after
    * its maximum value. Repetition of PES packets shall not occur. Consequently, no two consecutive PES packets in the
    * program multiplex shall have identical program_packet_sequence_counter values.
    */
    int8_t program_packet_sequence_counter; //7bits
    // 1bit const '1'
    /**
    * A 1-bit flag which when set to '1' indicates that this PES packet carries information from
    * an ISO/IEC 11172-1 stream. When set to '0' it indicates that this PES packet carries information from a Program Stream.
    */
    int8_t MPEG1_MPEG2_identifier; //1bit
    /**
    * This 6-bit field specifies the number of stuffing bytes used in the original ITU-T
    * Rec. H.222.0 | ISO/IEC 13818-1 PES packet header or in the original ISO/IEC 11172-1 packet header.
    */
    int8_t original_stuff_length; //6bits

    // 2B
    // 2bits const '01'
    /**
    * The P-STD_buffer_scale is a 1-bit field, the meaning of which is only defined if this PES packet
    * is contained in a Program Stream. It indicates the scaling factor used to interpret the subsequent P-STD_buffer_size field.
    * If the preceding stream_id indicates an audio stream, P-STD_buffer_scale shall have the value '0'. If the preceding
    * stream_id indicates a video stream, P-STD_buffer_scale shall have the value '1'. For all other stream types, the value
    * may be either '1' or '0'.
    */
    int8_t P_STD_buffer_scale; //1bit
    /**
    * The P-STD_buffer_size is a 13-bit unsigned integer, the meaning of which is only defined if this
    * PES packet is contained in a Program Stream. It defines the size of the input buffer, BS n , in the P-STD. If
    * P-STD_buffer_scale has the value '0', then the P-STD_buffer_size measures the buffer size in units of 128 bytes. If
    * P-STD_buffer_scale has the value '1', then the P-STD_buffer_size measures the buffer size in units of 1024 bytes.
    */
    int16_t P_STD_buffer_size; //13bits

    // (1+x)B
    // 1bit const '1'
    /**
    * This is a 7-bit field which specifies the length, in bytes, of the data following this field in
    * the PES extension field up to and including any reserved bytes.
    */
    u_int8_t PES_extension_field_length; //7bits
    char* PES_extension_field; //[PES_extension_field_length] bytes

    // NB
    /**
    * This is a fixed 8-bit value equal to '1111 1111' that can be inserted by the encoder, for example to meet
    * the requirements of the channel. It is discarded by the decoder. No more than 32 stuffing bytes shall be present in one
    * PES packet header.
    */
    int nb_stuffings;

    // NB
    /**
    * PES_packet_data_bytes shall be contiguous bytes of data from the elementary stream
    * indicated by the packet's stream_id or PID. When the elementary stream data conforms to ITU-T
    * Rec. H.262 | ISO/IEC 13818-2 or ISO/IEC 13818-3, the PES_packet_data_bytes shall be byte aligned to the bytes of this
    * Recommendation | International Standard. The byte-order of the elementary stream shall be preserved. The number of
    * PES_packet_data_bytes, N, is specified by the PES_packet_length field. N shall be equal to the value indicated in the
    * PES_packet_length minus the number of bytes between the last byte of the PES_packet_length field and the first
    * PES_packet_data_byte.
    *
    * In the case of a private_stream_1, private_stream_2, ECM_stream, or EMM_stream, the contents of the
    * PES_packet_data_byte field are user definable and will not be specified by ITU-T | ISO/IEC in the future.
    */
    int nb_bytes;

    // NB
    /**
    * This is a fixed 8-bit value equal to '1111 1111'. It is discarded by the decoder.
    */
    int nb_paddings;
public:
    SrsTsPayloadPES(SrsTsPacket* p);
    virtual ~SrsTsPayloadPES();
public:
    virtual int decode(SrsStream* stream, SrsTsMessage** ppmsg);
public:
    virtual int size();
    virtual int encode(SrsStream* stream);
private:
    virtual int decode_33bits_dts_pts(SrsStream* stream, int64_t* pv);
    virtual int encode_33bits_dts_pts(SrsStream* stream, u_int8_t fb, int64_t v);
};

/**
* the PSI payload of ts packet.
* 2.4.4 Program specific information, hls-mpeg-ts-iso13818-1.pdf, page 59
*/
class SrsTsPayloadPSI : public SrsTsPayload
{
public:
    // 1B
    /**
    * This is an 8-bit field whose value shall be the number of bytes, immediately following the pointer_field
    * until the first byte of the first section that is present in the payload of the Transport Stream packet (so a value of 0x00 in
    * the pointer_field indicates that the section starts immediately after the pointer_field). When at least one section begins in
    * a given Transport Stream packet, then the payload_unit_start_indicator (refer to 2.4.3.2) shall be set to 1 and the first
    * byte of the payload of that Transport Stream packet shall contain the pointer. When no section begins in a given
    * Transport Stream packet, then the payload_unit_start_indicator shall be set to 0 and no pointer shall be sent in the
    * payload of that packet.
    */
    int8_t pointer_field;
public:
    // 1B
    /**
    * This is an 8-bit field, which shall be set to 0x00 as shown in Table 2-26.
    */
    SrsTsPsiId table_id; //8bits
    
    // 2B
    /**
    * The section_syntax_indicator is a 1-bit field which shall be set to '1'.
    */
    int8_t section_syntax_indicator; //1bit
    /**
    * const value, must be '0'
    */
    int8_t const0_value; //1bit
    /**
    * reverved value, must be '1'
    */
    int8_t const1_value; //2bits
    /**
    * This is a 12-bit field, the first two bits of which shall be '00'. The remaining 10 bits specify the number
    * of bytes of the section, starting immediately following the section_length field, and including the CRC. The value in this
    * field shall not exceed 1021 (0x3FD).
    */
    u_int16_t section_length; //12bits
public:
    // the specified psi info, for example, PAT fields.
public:
    // 4B
    /**
    * This is a 32-bit field that contains the CRC value that gives a zero output of the registers in the decoder
    * defined in Annex A after processing the entire section.
    * @remark crc32(bytes without pointer field, before crc32 field)
    */
    int32_t CRC_32; //32bits
public:
    SrsTsPayloadPSI(SrsTsPacket* p);
    virtual ~SrsTsPayloadPSI();
public:
    virtual int decode(SrsStream* stream, SrsTsMessage** ppmsg);
public:
    virtual int size();
    virtual int encode(SrsStream* stream);
protected:
    virtual int psi_size() = 0;
    virtual int psi_encode(SrsStream* stream) = 0;
    virtual int psi_decode(SrsStream* stream) = 0;
};

/**
* the program of PAT of PSI ts packet.
*/
class SrsTsPayloadPATProgram
{
public:
    // 4B
    /**
    * Program_number is a 16-bit field. It specifies the program to which the program_map_PID is
    * applicable. When set to 0x0000, then the following PID reference shall be the network PID. For all other cases the value
    * of this field is user defined. This field shall not take any single value more than once within one version of the Program
    * Association Table.
    */
    int16_t number; // 16bits
    /**
    * reverved value, must be '1'
    */
    int8_t const1_value; //3bits
    /**
    * program_map_PID/network_PID 13bits
    * network_PID - The network_PID is a 13-bit field, which is used only in conjunction with the value of the
    * program_number set to 0x0000, specifies the PID of the Transport Stream packets which shall contain the Network
    * Information Table. The value of the network_PID field is defined by the user, but shall only take values as specified in
    * Table 2-3. The presence of the network_PID is optional.
    */
    int16_t pid; //13bits
public:
    SrsTsPayloadPATProgram(int16_t n = 0, int16_t p = 0);
    virtual ~SrsTsPayloadPATProgram();
public:
    virtual int decode(SrsStream* stream);
public:
    virtual int size();
    virtual int encode(SrsStream* stream);
};

/**
* the PAT payload of PSI ts packet.
* 2.4.4.3 Program association Table, hls-mpeg-ts-iso13818-1.pdf, page 61
* The Program Association Table provides the correspondence between a program_number and the PID value of the
* Transport Stream packets which carry the program definition. The program_number is the numeric label associated with
* a program.
*/
class SrsTsPayloadPAT : public SrsTsPayloadPSI
{
public:
    // 2B
    /**
    * This is a 16-bit field which serves as a label to identify this Transport Stream from any other
    * multiplex within a network. Its value is defined by the user.
    */
    u_int16_t transport_stream_id; //16bits
    
    // 1B
    /**
    * reverved value, must be '1'
    */
    int8_t const3_value; //2bits
    /**
    * This 5-bit field is the version number of the whole Program Association Table. The version number
    * shall be incremented by 1 modulo 32 whenever the definition of the Program Association Table changes. When the
    * current_next_indicator is set to '1', then the version_number shall be that of the currently applicable Program Association
    * Table. When the current_next_indicator is set to '0', then the version_number shall be that of the next applicable Program
    * Association Table.
    */
    int8_t version_number; //5bits
    /**
    * A 1-bit indicator, which when set to '1' indicates that the Program Association Table sent is
    * currently applicable. When the bit is set to '0', it indicates that the table sent is not yet applicable and shall be the next
    * table to become valid.
    */
    int8_t current_next_indicator; //1bit
    
    // 1B
    /**
    * This 8-bit field gives the number of this section. The section_number of the first section in the
    * Program Association Table shall be 0x00. It shall be incremented by 1 with each additional section in the Program
    * Association Table.
    */
    u_int8_t section_number; //8bits
    
    // 1B
    /**
    * This 8-bit field specifies the number of the last section (that is, the section with the highest
    * section_number) of the complete Program Association Table.
    */
    u_int8_t last_section_number; //8bits
    
    // multiple 4B program data.
    std::vector<SrsTsPayloadPATProgram*> programs;
public:
    SrsTsPayloadPAT(SrsTsPacket* p);
    virtual ~SrsTsPayloadPAT();
protected:
    virtual int psi_decode(SrsStream* stream);
protected:
    virtual int psi_size();
    virtual int psi_encode(SrsStream* stream);
};

/**
* the esinfo for PMT program.
*/
class SrsTsPayloadPMTESInfo
{
public:
    // 1B
    /**
    * This is an 8-bit field specifying the type of program element carried within the packets with the PID
    * whose value is specified by the elementary_PID. The values of stream_type are specified in Table 2-29.
    */
    SrsTsStream stream_type; //8bits
    
    // 2B
    /**
    * reverved value, must be '1'
    */
    int8_t const1_value0; //3bits
    /**
    * This is a 13-bit field specifying the PID of the Transport Stream packets which carry the associated
    * program element.
    */
    int16_t elementary_PID; //13bits
    
    // (2+x)B
    /**
    * reverved value, must be '1'
    */
    int8_t const1_value1; //4bits
    /**
    * This is a 12-bit field, the first two bits of which shall be '00'. The remaining 10 bits specify the number
    * of bytes of the descriptors of the associated program element immediately following the ES_info_length field.
    */
    int16_t ES_info_length; //12bits
    char* ES_info; //[ES_info_length] bytes.
public:
    SrsTsPayloadPMTESInfo(SrsTsStream st = SrsTsStreamReserved, int16_t epid = 0);
    virtual ~SrsTsPayloadPMTESInfo();
public:
    virtual int decode(SrsStream* stream);
public:
    virtual int size();
    virtual int encode(SrsStream* stream);
};

/**
* the PMT payload of PSI ts packet.
* 2.4.4.8 Program Map Table, hls-mpeg-ts-iso13818-1.pdf, page 64
* The Program Map Table provides the mappings between program numbers and the program elements that comprise
* them. A single instance of such a mapping is referred to as a "program definition". The program map table is the
* complete collection of all program definitions for a Transport Stream. This table shall be transmitted in packets, the PID
* values of which are selected by the encoder. More than one PID value may be used, if desired. The table is contained in
* one or more sections with the following syntax. It may be segmented to occupy multiple sections. In each section, the
* section number field shall be set to zero. Sections are identified by the program_number field.
*/
class SrsTsPayloadPMT : public SrsTsPayloadPSI
{
public:
    // 2B
    /**
    * program_number is a 16-bit field. It specifies the program to which the program_map_PID is
    * applicable. One program definition shall be carried within only one TS_program_map_section. This implies that a
    * program definition is never longer than 1016 (0x3F8). See Informative Annex C for ways to deal with the cases when
    * that length is not sufficient. The program_number may be used as a designation for a broadcast channel, for example. By
    * describing the different program elements belonging to a program, data from different sources (e.g. sequential events)
    * can be concatenated together to form a continuous set of streams using a program_number. For examples of applications
    * refer to Annex C.
    */
    u_int16_t program_number; //16bits
    
    // 1B
    /**
    * reverved value, must be '1'
    */
    int8_t const1_value0; //2bits
    /**
    * This 5-bit field is the version number of the TS_program_map_section. The version number shall be
    * incremented by 1 modulo 32 when a change in the information carried within the section occurs. Version number refers
    * to the definition of a single program, and therefore to a single section. When the current_next_indicator is set to '1', then
    * the version_number shall be that of the currently applicable TS_program_map_section. When the current_next_indicator
    * is set to '0', then the version_number shall be that of the next applicable TS_program_map_section.
    */
    int8_t version_number; //5bits
    /**
    * A 1-bit field, which when set to '1' indicates that the TS_program_map_section sent is
    * currently applicable. When the bit is set to '0', it indicates that the TS_program_map_section sent is not yet applicable
    * and shall be the next TS_program_map_section to become valid.
    */
    int8_t current_next_indicator; //1bit
    
    // 1B
    /**
    * The value of this 8-bit field shall be 0x00.
    */
    u_int8_t section_number; //8bits
    
    // 1B
    /**
    * The value of this 8-bit field shall be 0x00.
    */
    u_int8_t last_section_number; //8bits
    
    // 2B
    /**
    * reverved value, must be '1'
    */
    int8_t const1_value1; //3bits
    /**
    * This is a 13-bit field indicating the PID of the Transport Stream packets which shall contain the PCR fields
    * valid for the program specified by program_number. If no PCR is associated with a program definition for private
    * streams, then this field shall take the value of 0x1FFF. Refer to the semantic definition of PCR in 2.4.3.5 and Table 2-3
    * for restrictions on the choice of PCR_PID value.
    */
    int16_t PCR_PID; //13bits
    
    // 2B
    int8_t const1_value2; //4bits
    /**
    * This is a 12-bit field, the first two bits of which shall be '00'. The remaining 10 bits specify the
    * number of bytes of the descriptors immediately following the program_info_length field.
    */
    u_int16_t program_info_length; //12bits
    char* program_info_desc; //[program_info_length]bytes
    
    // array of TSPMTESInfo.
    std::vector<SrsTsPayloadPMTESInfo*> infos;
public:
    SrsTsPayloadPMT(SrsTsPacket* p);
    virtual ~SrsTsPayloadPMT();
protected:
    virtual int psi_decode(SrsStream* stream);
protected:
    virtual int psi_size();
    virtual int psi_encode(SrsStream* stream);
};

/**
* write data from frame(header info) and buffer(data) to ts file.
* it's a simple object wrapper for utility from nginx-rtmp: SrsMpegtsWriter
*/
class SrsTSMuxer
{
private:
    SrsCodecVideo vcodec;
    SrsCodecAudio acodec;
private:
    SrsTsContext* context;
    SrsFileWriter* writer;
    std::string path;
public:
    SrsTSMuxer(SrsFileWriter* w, SrsTsContext* c, SrsCodecAudio ac, SrsCodecVideo vc);
    virtual ~SrsTSMuxer();
public:
    /**
     * open the writer, donot write the PSI of ts.
     * @param p a string indicates the path of ts file to mux to.
     */
    virtual int open(std::string p);
    /**
    * when open ts, we donot write the header(PSI),
    * for user may need to update the acodec to mp3 or others,
    * so we use delay write PSI, when write audio or video.
    * @remark for audio aac codec, for example, SRS1, it's ok to write PSI when open ts.
    * @see https://github.com/ossrs/srs/issues/301
    */
    virtual int update_acodec(SrsCodecAudio ac);
    /**
    * write an audio frame to ts, 
    */
    virtual int write_audio(SrsTsMessage* audio);
    /**
    * write a video frame to ts, 
    */
    virtual int write_video(SrsTsMessage* video);
    /**
    * close the writer.
    */
    virtual void close();
public:
    /**
     * get the video codec of ts muxer.
     */
    virtual SrsCodecVideo video_codec();
};

/**
* ts stream cache, 
* use to cache ts stream.
* 
* about the flv tbn problem:
*   flv tbn is 1/1000, ts tbn is 1/90000,
*   when timestamp convert to flv tbn, it will loose precise,
*   so we must gather audio frame together, and recalc the timestamp @see SrsTsAacJitter,
*   we use a aac jitter to correct the audio pts.
*/
class SrsTsCache
{
public:
    // current ts message.
    SrsTsMessage* audio;
    SrsTsMessage* video;
public:
    SrsTsCache();
    virtual ~SrsTsCache();
public:
    /**
    * write audio to cache
    */
    virtual int cache_audio(SrsAvcAacCodec* codec, int64_t dts, SrsCodecSample* sample);
    /**
    * write video to muxer.
    */
    virtual int cache_video(SrsAvcAacCodec* codec, int64_t dts, SrsCodecSample* sample);
private:
    virtual int do_cache_mp3(SrsAvcAacCodec* codec, SrsCodecSample* sample);
    virtual int do_cache_aac(SrsAvcAacCodec* codec, SrsCodecSample* sample);
    virtual int do_cache_avc(SrsAvcAacCodec* codec, SrsCodecSample* sample);
};

/**
* encode data to ts file.
*/
class SrsTsEncoder
{
private:
    SrsFileWriter* writer;
private:
    SrsAvcAacCodec* codec;
    SrsCodecSample* sample;
    SrsTsCache* cache;
    SrsTSMuxer* muxer;
    SrsTsContext* context;
public:
    SrsTsEncoder();
    virtual ~SrsTsEncoder();
public:
    /**
     * initialize the underlayer file stream.
     * @param fw the writer to use for ts encoder, user must free it.
     */
    virtual int initialize(SrsFileWriter* fw);
public:
    /**
    * write audio/video packet.
    * @remark assert data is not NULL.
    */
    virtual int write_audio(int64_t timestamp, char* data, int size);
    virtual int write_video(int64_t timestamp, char* data, int size);
private:
    virtual int flush_audio();
    virtual int flush_video();
};

#endif

#endif