正在显示
3 个修改的文件
包含
437 行增加
和
109 行删除
| @@ -223,6 +223,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -223,6 +223,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 223 | #define ERROR_STREAM_CASTER_TS_SYNC_BYTE 4013 | 223 | #define ERROR_STREAM_CASTER_TS_SYNC_BYTE 4013 |
| 224 | #define ERROR_STREAM_CASTER_TS_AF 4014 | 224 | #define ERROR_STREAM_CASTER_TS_AF 4014 |
| 225 | #define ERROR_STREAM_CASTER_TS_CRC32 4015 | 225 | #define ERROR_STREAM_CASTER_TS_CRC32 4015 |
| 226 | +#define ERROR_STREAM_CASTER_TS_PSI 4016 | ||
| 227 | +#define ERROR_STREAM_CASTER_TS_PAT 4017 | ||
| 228 | +#define ERROR_STREAM_CASTER_TS_PMT 4018 | ||
| 226 | 229 | ||
| 227 | /** | 230 | /** |
| 228 | * whether the error code is an system control error. | 231 | * whether the error code is an system control error. |
| @@ -417,7 +417,7 @@ int SrsTsContext::decode(SrsStream* stream) | @@ -417,7 +417,7 @@ int SrsTsContext::decode(SrsStream* stream) | ||
| 417 | // parse util EOF of stream. | 417 | // parse util EOF of stream. |
| 418 | // for example, parse multiple times for the PES_packet_length(0) packet. | 418 | // for example, parse multiple times for the PES_packet_length(0) packet. |
| 419 | while (!stream->empty()) { | 419 | while (!stream->empty()) { |
| 420 | - SrsTsPacket* packet = new SrsTsPacket(); | 420 | + SrsTsPacket* packet = new SrsTsPacket(this); |
| 421 | SrsAutoFree(SrsTsPacket, packet); | 421 | SrsAutoFree(SrsTsPacket, packet); |
| 422 | 422 | ||
| 423 | if ((ret = packet->decode(stream)) != ERROR_SUCCESS) { | 423 | if ((ret = packet->decode(stream)) != ERROR_SUCCESS) { |
| @@ -429,8 +429,23 @@ int SrsTsContext::decode(SrsStream* stream) | @@ -429,8 +429,23 @@ int SrsTsContext::decode(SrsStream* stream) | ||
| 429 | return ret; | 429 | return ret; |
| 430 | } | 430 | } |
| 431 | 431 | ||
| 432 | -SrsTsPacket::SrsTsPacket() | 432 | +SrsTsPidApply SrsTsContext::get(int pid) |
| 433 | { | 433 | { |
| 434 | + if (pids.find(pid) == pids.end()) { | ||
| 435 | + return SrsTsPidApplyReserved; | ||
| 436 | + } | ||
| 437 | + return pids[pid]; | ||
| 438 | +} | ||
| 439 | + | ||
| 440 | +void SrsTsContext::set(int pid, SrsTsPidApply apply_pid) | ||
| 441 | +{ | ||
| 442 | + pids[pid] = apply_pid; | ||
| 443 | +} | ||
| 444 | + | ||
| 445 | +SrsTsPacket::SrsTsPacket(SrsTsContext* c) | ||
| 446 | +{ | ||
| 447 | + context = c; | ||
| 448 | + | ||
| 434 | sync_byte = 0; | 449 | sync_byte = 0; |
| 435 | transport_error_indicator = 0; | 450 | transport_error_indicator = 0; |
| 436 | payload_unit_start_indicator = 0; | 451 | payload_unit_start_indicator = 0; |
| @@ -508,9 +523,16 @@ int SrsTsPacket::decode(SrsStream* stream) | @@ -508,9 +523,16 @@ int SrsTsPacket::decode(SrsStream* stream) | ||
| 508 | srs_freep(payload); | 523 | srs_freep(payload); |
| 509 | payload = new SrsTsPayloadPAT(this); | 524 | payload = new SrsTsPayloadPAT(this); |
| 510 | } else { | 525 | } else { |
| 526 | + SrsTsPidApply apply_pid = context->get(pid); | ||
| 527 | + if (apply_pid == SrsTsPidApplyPMT) { | ||
| 528 | + // 2.4.4.8 Program Map Table | ||
| 529 | + srs_freep(payload); | ||
| 530 | + payload = new SrsTsPayloadPMT(this); | ||
| 531 | + } else { | ||
| 511 | // left bytes as reserved. | 532 | // left bytes as reserved. |
| 512 | stream->skip(nb_payload); | 533 | stream->skip(nb_payload); |
| 513 | } | 534 | } |
| 535 | + } | ||
| 514 | 536 | ||
| 515 | if (payload && (ret = payload->decode(stream)) != ERROR_SUCCESS) { | 537 | if (payload && (ret = payload->decode(stream)) != ERROR_SUCCESS) { |
| 516 | srs_error("ts: demux payload failed. ret=%d", ret); | 538 | srs_error("ts: demux payload failed. ret=%d", ret); |
| @@ -676,6 +698,7 @@ int SrsTsAdaptationField::decode(SrsStream* stream) | @@ -676,6 +698,7 @@ int SrsTsAdaptationField::decode(SrsStream* stream) | ||
| 676 | } | 698 | } |
| 677 | transport_private_data_length = (u_int8_t)stream->read_1bytes(); | 699 | transport_private_data_length = (u_int8_t)stream->read_1bytes(); |
| 678 | 700 | ||
| 701 | + if (transport_private_data_length> 0) { | ||
| 679 | if (!stream->require(transport_private_data_length)) { | 702 | if (!stream->require(transport_private_data_length)) { |
| 680 | ret = ERROR_STREAM_CASTER_TS_AF; | 703 | ret = ERROR_STREAM_CASTER_TS_AF; |
| 681 | srs_error("ts: demux af transport_private_data_flag failed. ret=%d", ret); | 704 | srs_error("ts: demux af transport_private_data_flag failed. ret=%d", ret); |
| @@ -685,6 +708,7 @@ int SrsTsAdaptationField::decode(SrsStream* stream) | @@ -685,6 +708,7 @@ int SrsTsAdaptationField::decode(SrsStream* stream) | ||
| 685 | transport_private_data = new char[transport_private_data_length]; | 708 | transport_private_data = new char[transport_private_data_length]; |
| 686 | stream->read_bytes(transport_private_data, transport_private_data_length); | 709 | stream->read_bytes(transport_private_data, transport_private_data_length); |
| 687 | } | 710 | } |
| 711 | + } | ||
| 688 | 712 | ||
| 689 | if (adaptation_field_extension_flag) { | 713 | if (adaptation_field_extension_flag) { |
| 690 | int pos_af_ext = stream->pos(); | 714 | int pos_af_ext = stream->pos(); |
| @@ -760,16 +784,6 @@ int SrsTsAdaptationField::decode(SrsStream* stream) | @@ -760,16 +784,6 @@ int SrsTsAdaptationField::decode(SrsStream* stream) | ||
| 760 | return ret; | 784 | return ret; |
| 761 | } | 785 | } |
| 762 | 786 | ||
| 763 | -SrsTsPayloadPATProgram::SrsTsPayloadPATProgram() | ||
| 764 | -{ | ||
| 765 | - number = 0; | ||
| 766 | - pid = 0; | ||
| 767 | -} | ||
| 768 | - | ||
| 769 | -SrsTsPayloadPATProgram::~SrsTsPayloadPATProgram() | ||
| 770 | -{ | ||
| 771 | -} | ||
| 772 | - | ||
| 773 | SrsTsPayload::SrsTsPayload(SrsTsPacket* p) | 787 | SrsTsPayload::SrsTsPayload(SrsTsPacket* p) |
| 774 | { | 788 | { |
| 775 | packet = p; | 789 | packet = p; |
| @@ -782,6 +796,7 @@ SrsTsPayload::~SrsTsPayload() | @@ -782,6 +796,7 @@ SrsTsPayload::~SrsTsPayload() | ||
| 782 | SrsTsPayloadPSI::SrsTsPayloadPSI(SrsTsPacket* p) : SrsTsPayload(p) | 796 | SrsTsPayloadPSI::SrsTsPayloadPSI(SrsTsPacket* p) : SrsTsPayload(p) |
| 783 | { | 797 | { |
| 784 | pointer_field = 0; | 798 | pointer_field = 0; |
| 799 | + CRC_32 = 0; | ||
| 785 | } | 800 | } |
| 786 | 801 | ||
| 787 | SrsTsPayloadPSI::~SrsTsPayloadPSI() | 802 | SrsTsPayloadPSI::~SrsTsPayloadPSI() |
| @@ -802,43 +817,21 @@ int SrsTsPayloadPSI::decode(SrsStream* stream) | @@ -802,43 +817,21 @@ int SrsTsPayloadPSI::decode(SrsStream* stream) | ||
| 802 | */ | 817 | */ |
| 803 | if (packet->payload_unit_start_indicator) { | 818 | if (packet->payload_unit_start_indicator) { |
| 804 | if (!stream->require(1)) { | 819 | if (!stream->require(1)) { |
| 805 | - ret = ERROR_STREAM_CASTER_TS_AF; | 820 | + ret = ERROR_STREAM_CASTER_TS_PSI; |
| 806 | srs_error("ts: demux PSI failed. ret=%d", ret); | 821 | srs_error("ts: demux PSI failed. ret=%d", ret); |
| 807 | return ret; | 822 | return ret; |
| 808 | } | 823 | } |
| 809 | pointer_field = stream->read_1bytes(); | 824 | pointer_field = stream->read_1bytes(); |
| 810 | } | 825 | } |
| 811 | 826 | ||
| 812 | - return ret; | ||
| 813 | -} | ||
| 814 | - | ||
| 815 | -SrsTsPayloadPAT::SrsTsPayloadPAT(SrsTsPacket* p) : SrsTsPayloadPSI(p) | ||
| 816 | -{ | ||
| 817 | - nb_programs = 0; | ||
| 818 | - programs = NULL; | ||
| 819 | -} | ||
| 820 | - | ||
| 821 | -SrsTsPayloadPAT::~SrsTsPayloadPAT() | ||
| 822 | -{ | ||
| 823 | - srs_freep(programs); | ||
| 824 | -} | ||
| 825 | - | ||
| 826 | -int SrsTsPayloadPAT::decode(SrsStream* stream) | ||
| 827 | -{ | ||
| 828 | - int ret = ERROR_SUCCESS; | ||
| 829 | - | ||
| 830 | - if ((ret = SrsTsPayloadPSI::decode(stream)) != ERROR_SUCCESS) { | ||
| 831 | - return ret; | ||
| 832 | - } | ||
| 833 | - | ||
| 834 | // to calc the crc32 | 827 | // to calc the crc32 |
| 835 | char* ppat = stream->data() + stream->pos(); | 828 | char* ppat = stream->data() + stream->pos(); |
| 836 | int pat_pos = stream->pos(); | 829 | int pat_pos = stream->pos(); |
| 837 | 830 | ||
| 838 | - // atleast 8B without programs and crc32 | ||
| 839 | - if (!stream->require(8)) { | ||
| 840 | - ret = ERROR_STREAM_CASTER_TS_AF; | ||
| 841 | - srs_error("ts: demux PAT failed. ret=%d", ret); | 831 | + // atleast 3B for all psi. |
| 832 | + if (!stream->require(3)) { | ||
| 833 | + ret = ERROR_STREAM_CASTER_TS_PSI; | ||
| 834 | + srs_error("ts: demux PSI failed. ret=%d", ret); | ||
| 842 | return ret; | 835 | return ret; |
| 843 | } | 836 | } |
| 844 | // 1B | 837 | // 1B |
| @@ -851,11 +844,82 @@ int SrsTsPayloadPAT::decode(SrsStream* stream) | @@ -851,11 +844,82 @@ int SrsTsPayloadPAT::decode(SrsStream* stream) | ||
| 851 | const0_value = (section_length >> 14) & 0x01; | 844 | const0_value = (section_length >> 14) & 0x01; |
| 852 | section_length &= 0x0FFF; | 845 | section_length &= 0x0FFF; |
| 853 | 846 | ||
| 847 | + // no section, ignore. | ||
| 848 | + if (section_length == 0) { | ||
| 849 | + srs_warn("ts: demux PAT ignore empty section"); | ||
| 850 | + return ret; | ||
| 851 | + } | ||
| 852 | + | ||
| 854 | if (!stream->require(section_length)) { | 853 | if (!stream->require(section_length)) { |
| 855 | - ret = ERROR_STREAM_CASTER_TS_AF; | 854 | + ret = ERROR_STREAM_CASTER_TS_PSI; |
| 856 | srs_error("ts: demux PAT section failed. ret=%d", ret); | 855 | srs_error("ts: demux PAT section failed. ret=%d", ret); |
| 857 | return ret; | 856 | return ret; |
| 858 | } | 857 | } |
| 858 | + | ||
| 859 | + // call the virtual method of actual PSI. | ||
| 860 | + if ((ret = psi_decode(stream)) != ERROR_SUCCESS) { | ||
| 861 | + return ret; | ||
| 862 | + } | ||
| 863 | + | ||
| 864 | + // 4B | ||
| 865 | + if (!stream->require(4)) { | ||
| 866 | + ret = ERROR_STREAM_CASTER_TS_PSI; | ||
| 867 | + srs_error("ts: demux PSI crc32 failed. ret=%d", ret); | ||
| 868 | + return ret; | ||
| 869 | + } | ||
| 870 | + CRC_32 = stream->read_4bytes(); | ||
| 871 | + | ||
| 872 | + // verify crc32. | ||
| 873 | + int32_t crc32 = srs_crc32(ppat, stream->pos() - pat_pos - 4); | ||
| 874 | + if (crc32 != CRC_32) { | ||
| 875 | + ret = ERROR_STREAM_CASTER_TS_CRC32; | ||
| 876 | + srs_error("ts: verify PSI crc32 failed. ret=%d", ret); | ||
| 877 | + return ret; | ||
| 878 | + } | ||
| 879 | + | ||
| 880 | + // consume left stuffings | ||
| 881 | + if (!stream->empty()) { | ||
| 882 | + stream->skip(stream->size() - stream->pos()); | ||
| 883 | + } | ||
| 884 | + | ||
| 885 | + return ret; | ||
| 886 | +} | ||
| 887 | + | ||
| 888 | +SrsTsPayloadPATProgram::SrsTsPayloadPATProgram() | ||
| 889 | +{ | ||
| 890 | + number = 0; | ||
| 891 | + pid = 0; | ||
| 892 | +} | ||
| 893 | + | ||
| 894 | +SrsTsPayloadPATProgram::~SrsTsPayloadPATProgram() | ||
| 895 | +{ | ||
| 896 | +} | ||
| 897 | + | ||
| 898 | +SrsTsPayloadPAT::SrsTsPayloadPAT(SrsTsPacket* p) : SrsTsPayloadPSI(p) | ||
| 899 | +{ | ||
| 900 | +} | ||
| 901 | + | ||
| 902 | +SrsTsPayloadPAT::~SrsTsPayloadPAT() | ||
| 903 | +{ | ||
| 904 | + std::vector<SrsTsPayloadPATProgram*>::iterator it; | ||
| 905 | + for (it = programs.begin(); it != programs.end(); ++it) { | ||
| 906 | + SrsTsPayloadPATProgram* program = *it; | ||
| 907 | + srs_freep(program); | ||
| 908 | + } | ||
| 909 | + programs.clear(); | ||
| 910 | +} | ||
| 911 | + | ||
| 912 | +int SrsTsPayloadPAT::psi_decode(SrsStream* stream) | ||
| 913 | +{ | ||
| 914 | + int ret = ERROR_SUCCESS; | ||
| 915 | + | ||
| 916 | + // atleast 5B for PAT specified | ||
| 917 | + if (!stream->require(5)) { | ||
| 918 | + ret = ERROR_STREAM_CASTER_TS_PAT; | ||
| 919 | + srs_error("ts: demux PAT failed. ret=%d", ret); | ||
| 920 | + return ret; | ||
| 921 | + } | ||
| 922 | + | ||
| 859 | int pos = stream->pos(); | 923 | int pos = stream->pos(); |
| 860 | 924 | ||
| 861 | // 2B | 925 | // 2B |
| @@ -876,35 +940,136 @@ int SrsTsPayloadPAT::decode(SrsStream* stream) | @@ -876,35 +940,136 @@ int SrsTsPayloadPAT::decode(SrsStream* stream) | ||
| 876 | 940 | ||
| 877 | // multiple 4B program data. | 941 | // multiple 4B program data. |
| 878 | int program_bytes = section_length - 4 - (stream->pos() - pos); | 942 | int program_bytes = section_length - 4 - (stream->pos() - pos); |
| 879 | - nb_programs = program_bytes / 4; | ||
| 880 | - if (nb_programs > 0) { | ||
| 881 | - srs_freep(programs); | ||
| 882 | - programs = new SrsTsPayloadPATProgram[nb_programs]; | ||
| 883 | - | ||
| 884 | - for (int i = 0; i < nb_programs; i++) { | ||
| 885 | - SrsTsPayloadPATProgram* program = programs + i; | 943 | + for (int i = 0; i < program_bytes; i += 4) { |
| 944 | + SrsTsPayloadPATProgram* program = new SrsTsPayloadPATProgram(); | ||
| 886 | 945 | ||
| 887 | int tmpv = stream->read_4bytes(); | 946 | int tmpv = stream->read_4bytes(); |
| 888 | program->number = (int16_t)((tmpv >> 16) & 0xFFFF); | 947 | program->number = (int16_t)((tmpv >> 16) & 0xFFFF); |
| 889 | program->pid = (int16_t)(tmpv & 0x1FFF); | 948 | program->pid = (int16_t)(tmpv & 0x1FFF); |
| 949 | + | ||
| 950 | + // update the apply pid table. | ||
| 951 | + packet->context->set(program->pid, SrsTsPidApplyPMT); | ||
| 952 | + | ||
| 953 | + programs.push_back(program); | ||
| 890 | } | 954 | } |
| 955 | + | ||
| 956 | + // update the apply pid table. | ||
| 957 | + packet->context->set(packet->pid, SrsTsPidApplyPAT); | ||
| 958 | + | ||
| 959 | + return ret; | ||
| 960 | +} | ||
| 961 | + | ||
| 962 | +SrsTsPayloadPMTESInfo::SrsTsPayloadPMTESInfo() | ||
| 963 | +{ | ||
| 964 | + ES_info_length = 0; | ||
| 965 | + ES_info = NULL; | ||
| 966 | +} | ||
| 967 | + | ||
| 968 | +SrsTsPayloadPMTESInfo::~SrsTsPayloadPMTESInfo() | ||
| 969 | +{ | ||
| 970 | + srs_freep(ES_info); | ||
| 971 | +} | ||
| 972 | + | ||
| 973 | +SrsTsPayloadPMT::SrsTsPayloadPMT(SrsTsPacket* p) : SrsTsPayloadPSI(p) | ||
| 974 | +{ | ||
| 975 | + program_info_length = 0; | ||
| 976 | + program_info_desc = NULL; | ||
| 977 | +} | ||
| 978 | + | ||
| 979 | +SrsTsPayloadPMT::~SrsTsPayloadPMT() | ||
| 980 | +{ | ||
| 981 | + srs_freep(program_info_desc); | ||
| 982 | + | ||
| 983 | + std::vector<SrsTsPayloadPMTESInfo*>::iterator it; | ||
| 984 | + for (it = infos.begin(); it != infos.end(); ++it) { | ||
| 985 | + SrsTsPayloadPMTESInfo* info = *it; | ||
| 986 | + srs_freep(info); | ||
| 891 | } | 987 | } |
| 988 | + infos.clear(); | ||
| 989 | +} | ||
| 892 | 990 | ||
| 893 | - // 4B | ||
| 894 | - if (!stream->require(4)) { | ||
| 895 | - ret = ERROR_STREAM_CASTER_TS_AF; | ||
| 896 | - srs_error("ts: demux PAT crc32 failed. ret=%d", ret); | 991 | +int SrsTsPayloadPMT::psi_decode(SrsStream* stream) |
| 992 | +{ | ||
| 993 | + int ret = ERROR_SUCCESS; | ||
| 994 | + | ||
| 995 | + // atleast 9B for PMT specified | ||
| 996 | + if (!stream->require(9)) { | ||
| 997 | + ret = ERROR_STREAM_CASTER_TS_PMT; | ||
| 998 | + srs_error("ts: demux PMT failed. ret=%d", ret); | ||
| 897 | return ret; | 999 | return ret; |
| 898 | } | 1000 | } |
| 899 | - CRC_32 = stream->read_4bytes(); | ||
| 900 | 1001 | ||
| 901 | - // verify crc32. | ||
| 902 | - int32_t crc32 = srs_crc32(ppat, stream->pos() - pat_pos - 4); | ||
| 903 | - if (crc32 != CRC_32) { | ||
| 904 | - ret = ERROR_STREAM_CASTER_TS_CRC32; | ||
| 905 | - srs_error("ts: verify PAT crc32 failed. ret=%d", ret); | 1002 | + // 2B |
| 1003 | + program_number = stream->read_2bytes(); | ||
| 1004 | + | ||
| 1005 | + // 1B | ||
| 1006 | + current_next_indicator = stream->read_1bytes(); | ||
| 1007 | + | ||
| 1008 | + version_number = (current_next_indicator >> 1) & 0x1F; | ||
| 1009 | + current_next_indicator &= 0x01; | ||
| 1010 | + | ||
| 1011 | + // 1B | ||
| 1012 | + section_number = stream->read_1bytes(); | ||
| 1013 | + | ||
| 1014 | + // 1B | ||
| 1015 | + last_section_number = stream->read_1bytes(); | ||
| 1016 | + | ||
| 1017 | + // 2B | ||
| 1018 | + PCR_PID = stream->read_2bytes(); | ||
| 1019 | + | ||
| 1020 | + PCR_PID &= 0x1FFF; | ||
| 1021 | + | ||
| 1022 | + // 2B | ||
| 1023 | + program_info_length = stream->read_2bytes(); | ||
| 1024 | + | ||
| 1025 | + program_info_length &= 0xFFF; | ||
| 1026 | + | ||
| 1027 | + if (program_info_length > 0) { | ||
| 1028 | + if (!stream->require(program_info_length)) { | ||
| 1029 | + ret = ERROR_STREAM_CASTER_TS_PMT; | ||
| 1030 | + srs_error("ts: demux PMT program info failed. ret=%d", ret); | ||
| 1031 | + return ret; | ||
| 1032 | + } | ||
| 1033 | + | ||
| 1034 | + srs_freep(program_info_desc); | ||
| 1035 | + program_info_desc = new char[program_info_length]; | ||
| 1036 | + stream->read_bytes(program_info_desc, program_info_length); | ||
| 1037 | + } | ||
| 1038 | + | ||
| 1039 | + // [section_length] - 4(CRC) - 9B - [program_info_length] | ||
| 1040 | + int ES_EOF_pos = stream->pos() + section_length - 4 - 9 - program_info_length; | ||
| 1041 | + while (stream->pos() < ES_EOF_pos) { | ||
| 1042 | + SrsTsPayloadPMTESInfo* info = new SrsTsPayloadPMTESInfo(); | ||
| 1043 | + infos.push_back(info); | ||
| 1044 | + | ||
| 1045 | + // 5B | ||
| 1046 | + if (!stream->require(5)) { | ||
| 1047 | + ret = ERROR_STREAM_CASTER_TS_PMT; | ||
| 1048 | + srs_error("ts: demux PMT es info failed. ret=%d", ret); | ||
| 1049 | + return ret; | ||
| 1050 | + } | ||
| 1051 | + | ||
| 1052 | + info->stream_type = stream->read_1bytes(); | ||
| 1053 | + info->elementary_PID = stream->read_2bytes(); | ||
| 1054 | + info->ES_info_length = stream->read_2bytes(); | ||
| 1055 | + | ||
| 1056 | + info->elementary_PID &= 0x1FFF; | ||
| 1057 | + info->ES_info_length &= 0x0FFF; | ||
| 1058 | + | ||
| 1059 | + if (info->ES_info_length > 0) { | ||
| 1060 | + if (!stream->require(info->ES_info_length)) { | ||
| 1061 | + ret = ERROR_STREAM_CASTER_TS_PMT; | ||
| 1062 | + srs_error("ts: demux PMT es info data failed. ret=%d", ret); | ||
| 906 | return ret; | 1063 | return ret; |
| 907 | } | 1064 | } |
| 1065 | + srs_freep(info->ES_info); | ||
| 1066 | + info->ES_info = new char[info->ES_info_length]; | ||
| 1067 | + stream->read_bytes(info->ES_info, info->ES_info_length); | ||
| 1068 | + } | ||
| 1069 | + } | ||
| 1070 | + | ||
| 1071 | + // update the apply pid table. | ||
| 1072 | + packet->context->set(packet->pid, SrsTsPidApplyPMT); | ||
| 908 | 1073 | ||
| 909 | return ret; | 1074 | return ret; |
| 910 | } | 1075 | } |
| @@ -30,6 +30,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -30,6 +30,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 30 | #include <srs_core.hpp> | 30 | #include <srs_core.hpp> |
| 31 | 31 | ||
| 32 | #include <string> | 32 | #include <string> |
| 33 | +#include <map> | ||
| 34 | +#include <vector> | ||
| 33 | 35 | ||
| 34 | #include <srs_kernel_codec.hpp> | 36 | #include <srs_kernel_codec.hpp> |
| 35 | 37 | ||
| @@ -64,6 +66,7 @@ public: | @@ -64,6 +66,7 @@ public: | ||
| 64 | /** | 66 | /** |
| 65 | * the pid of ts packet, | 67 | * the pid of ts packet, |
| 66 | * Table 2-3 ¨C PID table, hls-mpeg-ts-iso13818-1.pdf, page 37 | 68 | * Table 2-3 ¨C PID table, hls-mpeg-ts-iso13818-1.pdf, page 37 |
| 69 | +* NOTE ¨C The transport packets with PID values 0x0000, 0x0001, and 0x0010-0x1FFE are allowed to carry a PCR. | ||
| 67 | */ | 70 | */ |
| 68 | enum SrsTsPid | 71 | enum SrsTsPid |
| 69 | { | 72 | { |
| @@ -73,6 +76,12 @@ enum SrsTsPid | @@ -73,6 +76,12 @@ enum SrsTsPid | ||
| 73 | SrsTsPidCAT = 0x01, | 76 | SrsTsPidCAT = 0x01, |
| 74 | // Transport Stream Description Table | 77 | // Transport Stream Description Table |
| 75 | SrsTsPidTSDT = 0x02, | 78 | SrsTsPidTSDT = 0x02, |
| 79 | + // Reserved | ||
| 80 | + SrsTsPidReservedStart = 0x03, | ||
| 81 | + SrsTsPidReservedEnd = 0x0f, | ||
| 82 | + // May be assigned as network_PID, Program_map_PID, elementary_PID, or for other purposes | ||
| 83 | + SrsTsPidAppStart = 0x10, | ||
| 84 | + SrsTsPidAppEnd = 0x1ffe, | ||
| 76 | // null packets (see Table 2-3) | 85 | // null packets (see Table 2-3) |
| 77 | SrsTsPidNULL = 0x01FFF, | 86 | SrsTsPidNULL = 0x01FFF, |
| 78 | }; | 87 | }; |
| @@ -110,10 +119,27 @@ enum SrsTsAdaptationFieldType | @@ -110,10 +119,27 @@ enum SrsTsAdaptationFieldType | ||
| 110 | }; | 119 | }; |
| 111 | 120 | ||
| 112 | /** | 121 | /** |
| 122 | +* the actually parsed ts pid, | ||
| 123 | +* @see SrsTsPid, some pid, for example, PMT/Video/Audio is specified by PAT or other tables. | ||
| 124 | +*/ | ||
| 125 | +enum SrsTsPidApply | ||
| 126 | +{ | ||
| 127 | + SrsTsPidApplyReserved = 0, // TSPidTypeReserved, nothing parsed, used reserved. | ||
| 128 | + | ||
| 129 | + SrsTsPidApplyPAT, // Program associtate table | ||
| 130 | + SrsTsPidApplyPMT, // Program map table. | ||
| 131 | + | ||
| 132 | + SrsTsPidApplyVideo, // for video | ||
| 133 | + SrsTsPidApplyAudio, // vor audio | ||
| 134 | +}; | ||
| 135 | + | ||
| 136 | +/** | ||
| 113 | * the context of ts, to decode the ts stream. | 137 | * the context of ts, to decode the ts stream. |
| 114 | */ | 138 | */ |
| 115 | class SrsTsContext | 139 | class SrsTsContext |
| 116 | { | 140 | { |
| 141 | +private: | ||
| 142 | + std::map<int, SrsTsPidApply> pids; | ||
| 117 | public: | 143 | public: |
| 118 | SrsTsContext(); | 144 | SrsTsContext(); |
| 119 | virtual ~SrsTsContext(); | 145 | virtual ~SrsTsContext(); |
| @@ -123,6 +149,16 @@ public: | @@ -123,6 +149,16 @@ public: | ||
| 123 | * @remark we will consume all bytes in stream. | 149 | * @remark we will consume all bytes in stream. |
| 124 | */ | 150 | */ |
| 125 | virtual int decode(SrsStream* stream); | 151 | virtual int decode(SrsStream* stream); |
| 152 | +public: | ||
| 153 | + /** | ||
| 154 | + * get the pid apply, the parsed pid. | ||
| 155 | + * @return the apply pid; SrsTsPidApplyReserved for invalid. | ||
| 156 | + */ | ||
| 157 | + virtual SrsTsPidApply get(int pid); | ||
| 158 | + /** | ||
| 159 | + * set the pid apply, the parsed pid. | ||
| 160 | + */ | ||
| 161 | + virtual void set(int pid, SrsTsPidApply apply_pid); | ||
| 126 | }; | 162 | }; |
| 127 | 163 | ||
| 128 | /** | 164 | /** |
| @@ -204,7 +240,7 @@ public: | @@ -204,7 +240,7 @@ public: | ||
| 204 | /** | 240 | /** |
| 205 | * The continuity_counter is a 4-bit field incrementing with each Transport Stream packet with the | 241 | * The continuity_counter is a 4-bit field incrementing with each Transport Stream packet with the |
| 206 | * same PID. The continuity_counter wraps around to 0 after its maximum value. The continuity_counter shall not be | 242 | * same PID. The continuity_counter wraps around to 0 after its maximum value. The continuity_counter shall not be |
| 207 | - *incremented when the adaptation_field_control of the packet equals '00' or '10'. | 243 | + * incremented when the adaptation_field_control of the packet equals '00'(reseverd) or '10'(adaptation field only). |
| 208 | * | 244 | * |
| 209 | * In Transport Streams, duplicate packets may be sent as two, and only two, consecutive Transport Stream packets of the | 245 | * In Transport Streams, duplicate packets may be sent as two, and only two, consecutive Transport Stream packets of the |
| 210 | * same PID. The duplicate packets shall have the same continuity_counter value as the original packet and the | 246 | * same PID. The duplicate packets shall have the same continuity_counter value as the original packet and the |
| @@ -222,7 +258,9 @@ private: | @@ -222,7 +258,9 @@ private: | ||
| 222 | SrsTsAdaptationField* adaptation_field; | 258 | SrsTsAdaptationField* adaptation_field; |
| 223 | SrsTsPayload* payload; | 259 | SrsTsPayload* payload; |
| 224 | public: | 260 | public: |
| 225 | - SrsTsPacket(); | 261 | + SrsTsContext* context; |
| 262 | +public: | ||
| 263 | + SrsTsPacket(SrsTsContext* c); | ||
| 226 | virtual ~SrsTsPacket(); | 264 | virtual ~SrsTsPacket(); |
| 227 | public: | 265 | public: |
| 228 | virtual int decode(SrsStream* stream); | 266 | virtual int decode(SrsStream* stream); |
| @@ -561,34 +599,6 @@ enum SrsTsPsiId | @@ -561,34 +599,6 @@ enum SrsTsPsiId | ||
| 561 | }; | 599 | }; |
| 562 | 600 | ||
| 563 | /** | 601 | /** |
| 564 | -* the program of PAT of PSI ts packet. | ||
| 565 | -*/ | ||
| 566 | -class SrsTsPayloadPATProgram | ||
| 567 | -{ | ||
| 568 | -public: | ||
| 569 | - // 4B | ||
| 570 | - /** | ||
| 571 | - * Program_number is a 16-bit field. It specifies the program to which the program_map_PID is | ||
| 572 | - * applicable. When set to 0x0000, then the following PID reference shall be the network PID. For all other cases the value | ||
| 573 | - * of this field is user defined. This field shall not take any single value more than once within one version of the Program | ||
| 574 | - * Association Table. | ||
| 575 | - */ | ||
| 576 | - int16_t number; // 16bits | ||
| 577 | - // reserved 3bits | ||
| 578 | - /** | ||
| 579 | - * program_map_PID/network_PID 13bits | ||
| 580 | - * network_PID ¨C The network_PID is a 13-bit field, which is used only in conjunction with the value of the | ||
| 581 | - * program_number set to 0x0000, specifies the PID of the Transport Stream packets which shall contain the Network | ||
| 582 | - * Information Table. The value of the network_PID field is defined by the user, but shall only take values as specified in | ||
| 583 | - * Table 2-3. The presence of the network_PID is optional. | ||
| 584 | - */ | ||
| 585 | - int16_t pid; | ||
| 586 | -public: | ||
| 587 | - SrsTsPayloadPATProgram(); | ||
| 588 | - virtual ~SrsTsPayloadPATProgram(); | ||
| 589 | -}; | ||
| 590 | - | ||
| 591 | -/** | ||
| 592 | * the payload of ts packet, can be PES or PSI payload. | 602 | * the payload of ts packet, can be PES or PSI payload. |
| 593 | */ | 603 | */ |
| 594 | class SrsTsPayload | 604 | class SrsTsPayload |
| @@ -621,22 +631,6 @@ public: | @@ -621,22 +631,6 @@ public: | ||
| 621 | */ | 631 | */ |
| 622 | int8_t pointer_field; | 632 | int8_t pointer_field; |
| 623 | public: | 633 | public: |
| 624 | - SrsTsPayloadPSI(SrsTsPacket* p); | ||
| 625 | - virtual ~SrsTsPayloadPSI(); | ||
| 626 | -public: | ||
| 627 | - virtual int decode(SrsStream* stream); | ||
| 628 | -}; | ||
| 629 | - | ||
| 630 | -/** | ||
| 631 | -* the PAT payload of PSI ts packet. | ||
| 632 | -* 2.4.4.3 Program association Table, hls-mpeg-ts-iso13818-1.pdf, page 61 | ||
| 633 | -* The Program Association Table provides the correspondence between a program_number and the PID value of the | ||
| 634 | -* Transport Stream packets which carry the program definition. The program_number is the numeric label associated with | ||
| 635 | -* a program. | ||
| 636 | -*/ | ||
| 637 | -class SrsTsPayloadPAT : public SrsTsPayloadPSI | ||
| 638 | -{ | ||
| 639 | -public: | ||
| 640 | // 1B | 634 | // 1B |
| 641 | /** | 635 | /** |
| 642 | * This is an 8-bit field, which shall be set to 0x00 as shown in Table 2-26. | 636 | * This is an 8-bit field, which shall be set to 0x00 as shown in Table 2-26. |
| @@ -659,7 +653,61 @@ public: | @@ -659,7 +653,61 @@ public: | ||
| 659 | * field shall not exceed 1021 (0x3FD). | 653 | * field shall not exceed 1021 (0x3FD). |
| 660 | */ | 654 | */ |
| 661 | u_int16_t section_length; //12bits | 655 | u_int16_t section_length; //12bits |
| 656 | +public: | ||
| 657 | + // 4B | ||
| 658 | + /** | ||
| 659 | + * This is a 32-bit field that contains the CRC value that gives a zero output of the registers in the decoder | ||
| 660 | + * defined in Annex A after processing the entire section. | ||
| 661 | + * @remark crc32(bytes without pointer field, before crc32 field) | ||
| 662 | + */ | ||
| 663 | + int32_t CRC_32; //32bits | ||
| 664 | +public: | ||
| 665 | + SrsTsPayloadPSI(SrsTsPacket* p); | ||
| 666 | + virtual ~SrsTsPayloadPSI(); | ||
| 667 | +public: | ||
| 668 | + virtual int decode(SrsStream* stream); | ||
| 669 | +protected: | ||
| 670 | + virtual int psi_decode(SrsStream* stream) = 0; | ||
| 671 | +}; | ||
| 662 | 672 | ||
| 673 | +/** | ||
| 674 | +* the program of PAT of PSI ts packet. | ||
| 675 | +*/ | ||
| 676 | +class SrsTsPayloadPATProgram | ||
| 677 | +{ | ||
| 678 | +public: | ||
| 679 | + // 4B | ||
| 680 | + /** | ||
| 681 | + * Program_number is a 16-bit field. It specifies the program to which the program_map_PID is | ||
| 682 | + * applicable. When set to 0x0000, then the following PID reference shall be the network PID. For all other cases the value | ||
| 683 | + * of this field is user defined. This field shall not take any single value more than once within one version of the Program | ||
| 684 | + * Association Table. | ||
| 685 | + */ | ||
| 686 | + int16_t number; // 16bits | ||
| 687 | + // reserved 3bits | ||
| 688 | + /** | ||
| 689 | + * program_map_PID/network_PID 13bits | ||
| 690 | + * network_PID ¨C The network_PID is a 13-bit field, which is used only in conjunction with the value of the | ||
| 691 | + * program_number set to 0x0000, specifies the PID of the Transport Stream packets which shall contain the Network | ||
| 692 | + * Information Table. The value of the network_PID field is defined by the user, but shall only take values as specified in | ||
| 693 | + * Table 2-3. The presence of the network_PID is optional. | ||
| 694 | + */ | ||
| 695 | + int16_t pid; | ||
| 696 | +public: | ||
| 697 | + SrsTsPayloadPATProgram(); | ||
| 698 | + virtual ~SrsTsPayloadPATProgram(); | ||
| 699 | +}; | ||
| 700 | + | ||
| 701 | +/** | ||
| 702 | +* the PAT payload of PSI ts packet. | ||
| 703 | +* 2.4.4.3 Program association Table, hls-mpeg-ts-iso13818-1.pdf, page 61 | ||
| 704 | +* The Program Association Table provides the correspondence between a program_number and the PID value of the | ||
| 705 | +* Transport Stream packets which carry the program definition. The program_number is the numeric label associated with | ||
| 706 | +* a program. | ||
| 707 | +*/ | ||
| 708 | +class SrsTsPayloadPAT : public SrsTsPayloadPSI | ||
| 709 | +{ | ||
| 710 | +public: | ||
| 663 | // 2B | 711 | // 2B |
| 664 | /** | 712 | /** |
| 665 | * This is a 16-bit field which serves as a label to identify this Transport Stream from any other | 713 | * This is a 16-bit field which serves as a label to identify this Transport Stream from any other |
| @@ -700,16 +748,128 @@ public: | @@ -700,16 +748,128 @@ public: | ||
| 700 | u_int8_t last_section_number; //8bits | 748 | u_int8_t last_section_number; //8bits |
| 701 | 749 | ||
| 702 | // multiple 4B program data. | 750 | // multiple 4B program data. |
| 703 | - int nb_programs; | ||
| 704 | - SrsTsPayloadPATProgram* programs; | ||
| 705 | - | ||
| 706 | - // 4B | ||
| 707 | - int32_t CRC_32; //32bits | 751 | + std::vector<SrsTsPayloadPATProgram*> programs; |
| 708 | public: | 752 | public: |
| 709 | SrsTsPayloadPAT(SrsTsPacket* p); | 753 | SrsTsPayloadPAT(SrsTsPacket* p); |
| 710 | virtual ~SrsTsPayloadPAT(); | 754 | virtual ~SrsTsPayloadPAT(); |
| 711 | public: | 755 | public: |
| 712 | - virtual int decode(SrsStream* stream); | 756 | + virtual int psi_decode(SrsStream* stream); |
| 757 | +}; | ||
| 758 | + | ||
| 759 | +/** | ||
| 760 | +* the esinfo for PMT program. | ||
| 761 | +*/ | ||
| 762 | +class SrsTsPayloadPMTESInfo | ||
| 763 | +{ | ||
| 764 | +public: | ||
| 765 | + // 1B | ||
| 766 | + /** | ||
| 767 | + * This is an 8-bit field specifying the type of program element carried within the packets with the PID | ||
| 768 | + * whose value is specified by the elementary_PID. The values of stream_type are specified in Table 2-29. | ||
| 769 | + */ | ||
| 770 | + u_int8_t stream_type; //8bits | ||
| 771 | + | ||
| 772 | + // 2B | ||
| 773 | + // 3bits reserved | ||
| 774 | + /** | ||
| 775 | + * This is a 13-bit field specifying the PID of the Transport Stream packets which carry the associated | ||
| 776 | + * program element. | ||
| 777 | + */ | ||
| 778 | + int16_t elementary_PID; //13bits | ||
| 779 | + | ||
| 780 | + // 2B | ||
| 781 | + // 4bits reserved | ||
| 782 | + /** | ||
| 783 | + * This is a 12-bit field, the first two bits of which shall be '00'. The remaining 10 bits specify the number | ||
| 784 | + * of bytes of the descriptors of the associated program element immediately following the ES_info_length field. | ||
| 785 | + */ | ||
| 786 | + int16_t ES_info_length; //12bits | ||
| 787 | + char* ES_info; //[ES_info_length] bytes. | ||
| 788 | +public: | ||
| 789 | + SrsTsPayloadPMTESInfo(); | ||
| 790 | + virtual ~SrsTsPayloadPMTESInfo(); | ||
| 791 | +}; | ||
| 792 | + | ||
| 793 | +/** | ||
| 794 | +* the PMT payload of PSI ts packet. | ||
| 795 | +* 2.4.4.8 Program Map Table, hls-mpeg-ts-iso13818-1.pdf, page 64 | ||
| 796 | +* The Program Map Table provides the mappings between program numbers and the program elements that comprise | ||
| 797 | +* them. A single instance of such a mapping is referred to as a "program definition". The program map table is the | ||
| 798 | +* complete collection of all program definitions for a Transport Stream. This table shall be transmitted in packets, the PID | ||
| 799 | +* values of which are selected by the encoder. More than one PID value may be used, if desired. The table is contained in | ||
| 800 | +* one or more sections with the following syntax. It may be segmented to occupy multiple sections. In each section, the | ||
| 801 | +* section number field shall be set to zero. Sections are identified by the program_number field. | ||
| 802 | +*/ | ||
| 803 | +class SrsTsPayloadPMT : public SrsTsPayloadPSI | ||
| 804 | +{ | ||
| 805 | +public: | ||
| 806 | + // 2B | ||
| 807 | + /** | ||
| 808 | + * program_number is a 16-bit field. It specifies the program to which the program_map_PID is | ||
| 809 | + * applicable. One program definition shall be carried within only one TS_program_map_section. This implies that a | ||
| 810 | + * program definition is never longer than 1016 (0x3F8). See Informative Annex C for ways to deal with the cases when | ||
| 811 | + * that length is not sufficient. The program_number may be used as a designation for a broadcast channel, for example. By | ||
| 812 | + * describing the different program elements belonging to a program, data from different sources (e.g. sequential events) | ||
| 813 | + * can be concatenated together to form a continuous set of streams using a program_number. For examples of applications | ||
| 814 | + * refer to Annex C. | ||
| 815 | + */ | ||
| 816 | + u_int16_t program_number; //16bits | ||
| 817 | + | ||
| 818 | + // 1B | ||
| 819 | + // 2bits reerverd. | ||
| 820 | + /** | ||
| 821 | + * This 5-bit field is the version number of the TS_program_map_section. The version number shall be | ||
| 822 | + * incremented by 1 modulo 32 when a change in the information carried within the section occurs. Version number refers | ||
| 823 | + * to the definition of a single program, and therefore to a single section. When the current_next_indicator is set to '1', then | ||
| 824 | + * the version_number shall be that of the currently applicable TS_program_map_section. When the current_next_indicator | ||
| 825 | + * is set to '0', then the version_number shall be that of the next applicable TS_program_map_section. | ||
| 826 | + */ | ||
| 827 | + int8_t version_number; //5bits | ||
| 828 | + /** | ||
| 829 | + * A 1-bit field, which when set to '1' indicates that the TS_program_map_section sent is | ||
| 830 | + * currently applicable. When the bit is set to '0', it indicates that the TS_program_map_section sent is not yet applicable | ||
| 831 | + * and shall be the next TS_program_map_section to become valid. | ||
| 832 | + */ | ||
| 833 | + int8_t current_next_indicator; //1bit | ||
| 834 | + | ||
| 835 | + // 1B | ||
| 836 | + /** | ||
| 837 | + * The value of this 8-bit field shall be 0x00. | ||
| 838 | + */ | ||
| 839 | + u_int8_t section_number; //8bits | ||
| 840 | + | ||
| 841 | + // 1B | ||
| 842 | + /** | ||
| 843 | + * The value of this 8-bit field shall be 0x00. | ||
| 844 | + */ | ||
| 845 | + u_int8_t last_section_number; //8bits | ||
| 846 | + | ||
| 847 | + // 2B | ||
| 848 | + // 2bits reserved. | ||
| 849 | + /** | ||
| 850 | + * This is a 13-bit field indicating the PID of the Transport Stream packets which shall contain the PCR fields | ||
| 851 | + * valid for the program specified by program_number. If no PCR is associated with a program definition for private | ||
| 852 | + * 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 | ||
| 853 | + * for restrictions on the choice of PCR_PID value. | ||
| 854 | + */ | ||
| 855 | + int16_t PCR_PID; //16bits | ||
| 856 | + | ||
| 857 | + // 2B | ||
| 858 | + // 4bits reserved. | ||
| 859 | + /** | ||
| 860 | + * This is a 12-bit field, the first two bits of which shall be '00'. The remaining 10 bits specify the | ||
| 861 | + * number of bytes of the descriptors immediately following the program_info_length field. | ||
| 862 | + */ | ||
| 863 | + u_int16_t program_info_length; //12bits | ||
| 864 | + char* program_info_desc; //[program_info_length]bytes | ||
| 865 | + | ||
| 866 | + // array of TSPMTESInfo. | ||
| 867 | + std::vector<SrsTsPayloadPMTESInfo*> infos; | ||
| 868 | +public: | ||
| 869 | + SrsTsPayloadPMT(SrsTsPacket* p); | ||
| 870 | + virtual ~SrsTsPayloadPMT(); | ||
| 871 | +public: | ||
| 872 | + virtual int psi_decode(SrsStream* stream); | ||
| 713 | }; | 873 | }; |
| 714 | 874 | ||
| 715 | /** | 875 | /** |
-
请 注册 或 登录 后发表评论