正在显示
3 个修改的文件
包含
455 行增加
和
127 行删除
@@ -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,8 +523,15 @@ int SrsTsPacket::decode(SrsStream* stream) | @@ -508,8 +523,15 @@ 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 { |
511 | - // left bytes as reserved. | ||
512 | - stream->skip(nb_payload); | 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 { | ||
532 | + // left bytes as reserved. | ||
533 | + stream->skip(nb_payload); | ||
534 | + } | ||
513 | } | 535 | } |
514 | 536 | ||
515 | if (payload && (ret = payload->decode(stream)) != ERROR_SUCCESS) { | 537 | if (payload && (ret = payload->decode(stream)) != ERROR_SUCCESS) { |
@@ -676,14 +698,16 @@ int SrsTsAdaptationField::decode(SrsStream* stream) | @@ -676,14 +698,16 @@ 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 | ||
679 | - if (!stream->require(transport_private_data_length)) { | ||
680 | - ret = ERROR_STREAM_CASTER_TS_AF; | ||
681 | - srs_error("ts: demux af transport_private_data_flag failed. ret=%d", ret); | ||
682 | - return ret; | 701 | + if (transport_private_data_length> 0) { |
702 | + if (!stream->require(transport_private_data_length)) { | ||
703 | + ret = ERROR_STREAM_CASTER_TS_AF; | ||
704 | + srs_error("ts: demux af transport_private_data_flag failed. ret=%d", ret); | ||
705 | + return ret; | ||
706 | + } | ||
707 | + srs_freep(transport_private_data); | ||
708 | + transport_private_data = new char[transport_private_data_length]; | ||
709 | + stream->read_bytes(transport_private_data, transport_private_data_length); | ||
683 | } | 710 | } |
684 | - srs_freep(transport_private_data); | ||
685 | - transport_private_data = new char[transport_private_data_length]; | ||
686 | - stream->read_bytes(transport_private_data, transport_private_data_length); | ||
687 | } | 711 | } |
688 | 712 | ||
689 | if (adaptation_field_extension_flag) { | 713 | if (adaptation_field_extension_flag) { |
@@ -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,36 +940,137 @@ int SrsTsPayloadPAT::decode(SrsStream* stream) | @@ -876,36 +940,137 @@ 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]; | 943 | + for (int i = 0; i < program_bytes; i += 4) { |
944 | + SrsTsPayloadPATProgram* program = new SrsTsPayloadPATProgram(); | ||
883 | 945 | ||
884 | - for (int i = 0; i < nb_programs; i++) { | ||
885 | - SrsTsPayloadPATProgram* program = programs + i; | 946 | + int tmpv = stream->read_4bytes(); |
947 | + program->number = (int16_t)((tmpv >> 16) & 0xFFFF); | ||
948 | + program->pid = (int16_t)(tmpv & 0x1FFF); | ||
886 | 949 | ||
887 | - int tmpv = stream->read_4bytes(); | ||
888 | - program->number = (int16_t)((tmpv >> 16) & 0xFFFF); | ||
889 | - program->pid = (int16_t)(tmpv & 0x1FFF); | ||
890 | - } | 950 | + // update the apply pid table. |
951 | + packet->context->set(program->pid, SrsTsPidApplyPMT); | ||
952 | + | ||
953 | + programs.push_back(program); | ||
891 | } | 954 | } |
892 | - | ||
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); | ||
897 | - return ret; | 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); | ||
898 | } | 987 | } |
899 | - CRC_32 = stream->read_4bytes(); | 988 | + infos.clear(); |
989 | +} | ||
900 | 990 | ||
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); | 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); | ||
906 | return ret; | 999 | return ret; |
907 | } | 1000 | } |
908 | 1001 | ||
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); | ||
1063 | + return ret; | ||
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); | ||
1073 | + | ||
909 | return ret; | 1074 | return ret; |
910 | } | 1075 | } |
911 | 1076 |
@@ -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,15 +66,22 @@ public: | @@ -64,15 +66,22 @@ 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 | { |
70 | // Program Association Table(see Table 2-25). | 73 | // Program Association Table(see Table 2-25). |
71 | - SrsTsPidPAT = 0x00, | 74 | + SrsTsPidPAT = 0x00, |
72 | // Conditional Access Table (see Table 2-27). | 75 | // Conditional Access Table (see Table 2-27). |
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 |
662 | - | 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 | +}; | ||
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 | /** |
-
请 注册 或 登录 后发表评论