diff --git a/trunk/src/kernel/srs_kernel_ts.cpp b/trunk/src/kernel/srs_kernel_ts.cpp index c3c43a1a3..3d135b55a 100644 --- a/trunk/src/kernel/srs_kernel_ts.cpp +++ b/trunk/src/kernel/srs_kernel_ts.cpp @@ -402,6 +402,14 @@ SrsMpegtsFrame::SrsMpegtsFrame() SrsTsPacket::SrsTsPacket() { + sync_byte = 0; + transport_error_indicator = 0; + payload_unit_start_indicator = 0; + transport_priority = 0; + pid = SrsTsPidPAT; + transport_scrambling_control = SrsTsScrambledDisabled; + adaption_field_control = SrsTsAdaptationFieldTypeReserved; + continuity_counter = 0; adaptation_field = NULL; } @@ -410,6 +418,46 @@ SrsTsPacket::~SrsTsPacket() srs_freep(adaptation_field); } +SrsTsAdaptationField::SrsTsAdaptationField() +{ + adaption_field_length = 0; + discontinuity_indicator = 0; + random_access_indicator = 0; + elementary_stream_priority_indicator = 0; + PCR_flag = 0; + OPCR_flag = 0; + splicing_point_flag = 0; + transport_private_data_flag = 0; + adaptation_field_extension_flag = 0; + program_clock_reference_base = 0; + program_clock_reference_extension = 0; + original_program_clock_reference_base = 0; + original_program_clock_reference_extension = 0; + splice_countdown = 0; + transport_private_data_length = 0; + transport_private_data = NULL; + adaptation_field_extension_length = 0; + ltw_flag = 0; + piecewise_rate_flag = 0; + seamless_splice_flag = 0; + ltw_valid_flag = 0; + ltw_offset = 0; + piecewise_rate = 0; + splice_type = 0; + DTS_next_AU0 = 0; + marker_bit0 = 0; + DTS_next_AU1 = 0; + marker_bit1 = 0; + DTS_next_AU2 = 0; + marker_bit2 = 0; + nb_af_ext_reserved = 0; + nb_af_reserved = 0; +} + +SrsTsAdaptationField::~SrsTsAdaptationField() +{ +} + SrsTSMuxer::SrsTSMuxer(SrsFileWriter* w) { writer = w; diff --git a/trunk/src/kernel/srs_kernel_ts.hpp b/trunk/src/kernel/srs_kernel_ts.hpp index 22917dedc..bf5c29f9f 100644 --- a/trunk/src/kernel/srs_kernel_ts.hpp +++ b/trunk/src/kernel/srs_kernel_ts.hpp @@ -40,6 +40,7 @@ class SrsFileReader; class SrsAvcAacCodec; class SrsCodecSample; class SrsSimpleBuffer; +class SrsTsAdaptationField; // Transport Stream packets are 188 bytes in length. #define SRS_TS_PACKET_SIZE 188 @@ -106,10 +107,6 @@ enum SrsTsAdaptationFieldType SrsTsAdaptationFieldTypeBoth = 0x03, }; -class SrsTsAdaptationField -{ -}; - /** * the packet in ts stream, * 2.4.3.2 Transport Stream packet layer, hls-mpeg-ts-iso13818-1.pdf, page 36 @@ -118,11 +115,14 @@ class SrsTsAdaptationField class SrsTsPacket { private: + // 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 @@ -166,6 +166,8 @@ private: * 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 @@ -206,6 +208,304 @@ public: public: }; +/** +* 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 +{ +private: + // 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. + 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. + 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 + //5bits reserved + // 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; +public: + SrsTsAdaptationField(); + virtual ~SrsTsAdaptationField(); +public: +}; + /** * write data from frame(header info) and buffer(data) to ts file. * it's a simple object wrapper for utility from nginx-rtmp: SrsMpegtsWriter