mirror of
https://github.com/ossrs/srs.git
synced 2025-02-15 04:42:04 +00:00
318 lines
14 KiB
C++
318 lines
14 KiB
C++
//
|
||
// Copyright (c) 2013-2024 The SRS Authors
|
||
//
|
||
// SPDX-License-Identifier: MIT
|
||
//
|
||
|
||
#ifndef SRS_KERNEL_PS_HPP
|
||
#define SRS_KERNEL_PS_HPP
|
||
|
||
#include <srs_core.hpp>
|
||
|
||
#include <srs_kernel_ts.hpp>
|
||
|
||
class SrsPsPacket;
|
||
class SrsPsContext;
|
||
|
||
// The helper for PS decoding.
|
||
struct SrsPsDecodeHelper
|
||
{
|
||
public:
|
||
// For debugging to get the RTP packet source. Not used in context.
|
||
uint16_t rtp_seq_;
|
||
// For debugging to get the RTP packet timestamp. Not used in context.
|
||
uint32_t rtp_ts_;
|
||
// For debugging to get the RTP packet payload type. Not used in context.
|
||
uint8_t rtp_pt_;
|
||
public:
|
||
// For debugging, current pack id. Not used in context.
|
||
uint32_t pack_id_;
|
||
// For debugging, the first sequence of current pack. Not used in context.
|
||
uint16_t pack_first_seq_;
|
||
// For debugging, the last sequence of previous message in current pack. Not used in context.
|
||
uint16_t pack_pre_msg_last_seq_;
|
||
// For debugging, the number of messages in pack. Not used in context.
|
||
uint16_t pack_nn_msgs_;
|
||
public:
|
||
// The PS context for decoding.
|
||
SrsPsContext* ctx_;
|
||
// The PS packet for decoding.
|
||
SrsPsPacket* ps_;
|
||
public:
|
||
SrsPsDecodeHelper();
|
||
};
|
||
|
||
// The PS message handler.
|
||
class ISrsPsMessageHandler : public ISrsTsHandler
|
||
{
|
||
public:
|
||
ISrsPsMessageHandler();
|
||
virtual ~ISrsPsMessageHandler();
|
||
public:
|
||
// When enter recover mode, user should drop all messages in pack. The nn_recover indicates the number of retry
|
||
// during recovery, that is 0 for the first time, and 1 for the second time.
|
||
virtual void on_recover_mode(int nn_recover) = 0;
|
||
};
|
||
|
||
// The PS context, to process PS PES stream.
|
||
class SrsPsContext
|
||
{
|
||
public:
|
||
SrsPsDecodeHelper helper_;
|
||
private:
|
||
// The last decoding PS(TS) message.
|
||
SrsTsMessage* last_;
|
||
// The current parsing PS packet context.
|
||
SrsPsPacket* current_;
|
||
// Whether detect PS packet header integrity.
|
||
bool detect_ps_integrity_;
|
||
public:
|
||
// The stream type parsed from latest PSM packet.
|
||
SrsTsStream video_stream_type_;
|
||
SrsTsStream audio_stream_type_;
|
||
public:
|
||
SrsPsContext();
|
||
virtual ~SrsPsContext();
|
||
public:
|
||
// Set whether detecting PS header integrity.
|
||
void set_detect_ps_integrity(bool v);
|
||
// Get the last PS(TS) message. Create one if not exists.
|
||
SrsTsMessage* last();
|
||
// Reap the last message and create a fresh one.
|
||
SrsTsMessage* reap();
|
||
public:
|
||
// Feed with ts packets, decode as ts message, callback handler if got one ts message.
|
||
// A ts video message can be decoded to NALUs by SrsRawH264Stream::annexb_demux.
|
||
// A ts audio message can be decoded to RAW frame by SrsRawAacStream::adts_demux.
|
||
// @param handler The ts message handler to process the msg.
|
||
// @remark We will consume all bytes in stream.
|
||
virtual srs_error_t decode(SrsBuffer* stream, ISrsPsMessageHandler* handler);
|
||
private:
|
||
srs_error_t do_decode(SrsBuffer* stream, ISrsPsMessageHandler* handler);
|
||
};
|
||
|
||
// The packet in ps stream.
|
||
// 2.5.3.3 Pack layer of Program Stream, hls-mpeg-ts-iso13818-1.pdf, page 73
|
||
class SrsPsPacket
|
||
{
|
||
public:
|
||
SrsPsContext* context_;
|
||
public:
|
||
// The global ID of pack header. The low 16 bits is reserved for seq. Automatically generate the high bits in
|
||
// constructor.
|
||
uint32_t id_;
|
||
// Whether the PS pack stream has pack and system header.
|
||
bool has_pack_header_;
|
||
bool has_system_header_;
|
||
// Table 2-33 – Program Stream pack header, hls-mpeg-ts-iso13818-1.pdf, page 73
|
||
public:
|
||
// 4B
|
||
// The pack_start_code is the bit string '0000 0000 0000 0000 0000 0001 1011 1010' (0x000001BA). It identifies the
|
||
// beginning of a pack.
|
||
uint32_t pack_start_code_; // 32bits
|
||
|
||
// 6B
|
||
// 2bits const '01'
|
||
// 3bits system_clock_reference_base [32..30]
|
||
// 1bit marker_bit '1'
|
||
// 15bits system_clock_reference_base [29..15]
|
||
// 1bit marker_bit '1'
|
||
// 22bits system_clock_reference_base [14..0]
|
||
// 1bit marker_bit '1'
|
||
// 9bits system_clock_reference_extension
|
||
// 1bit marker_bit '1'
|
||
// The system clock reference (SCR) is a 42-bit field coded in two parts. The first part,
|
||
// system_clock_reference_base, is a 33-bit field whose value is given by SCR_base(i) as given in equation 2-19.
|
||
// The second part, system_clock_reference_extension, is a 9-bit field whose value is given by SCR_ext(i), as given
|
||
// in equation 2-20. The SCR indicates the intended time of arrival of the byte containing the last bit of the
|
||
// system_clock_reference_base at the input of the program target decoder.
|
||
uint64_t system_clock_reference_base_; // 32bits
|
||
uint16_t system_clock_reference_extension_; // 9bits
|
||
|
||
// 3B
|
||
// 22bits program_mux_rate
|
||
// 1bit marker_bit '1'
|
||
// 1bit marker_bit '1'
|
||
// This is a 22-bit integer specifying the rate at which the P-STD receives the Program Stream during the pack in
|
||
// which it is included. The value of program_mux_rate is measured in units of 50 bytes/second. The value 0 is
|
||
// forbidden. The value represented in program_mux_rate is used to define the time of arrival of bytes at the input
|
||
// to the P-STD in 2.5.2. The value encoded in the program_mux_rate field may vary from pack to pack in an ITU-T
|
||
// Rec. H.222.0 | ISO/IEC 13818-1 program multiplexed stream.
|
||
uint32_t program_mux_rate_; // 22bits
|
||
|
||
// 1B
|
||
// 5bits reserved
|
||
// 3bits pack_stuffing_length
|
||
// A 3-bit integer specifying the number of stuffing bytes which follow this field.
|
||
uint8_t pack_stuffing_length_; // 3bits
|
||
// Table 2-34 – Program Stream system header, hls-mpeg-ts-iso13818-1.pdf, page 74
|
||
public:
|
||
// 4B
|
||
// The system_header_start_code is the bit string '0000 0000 0000 0000 0000 0001 1011 1011' (0x000001BB). It
|
||
// identifies the beginning of a system header.
|
||
uint32_t system_header_start_code_;
|
||
|
||
// 2B
|
||
// This 16-bit field indicates the length in bytes of the system header following the header_length field. Future
|
||
// extensions of this Specification may extend the system header.
|
||
uint16_t header_length_;
|
||
|
||
// 3B
|
||
// 1bit marker_bit '1'
|
||
// 22bits rate_bound
|
||
// 1bit marker_bit '1'
|
||
// A 22-bit field. The rate_bound is an integer value greater than or equal to the maximum value of the
|
||
// program_mux_rate field coded in any pack of the Program Stream. It may be used by a decoder to assess whether it
|
||
// is capable of decoding the entire stream.
|
||
uint32_t rate_bound_;
|
||
|
||
// 1B
|
||
// 6bits audio_bound
|
||
// 1bit fixed_flag
|
||
// 1bit CSPS_flag
|
||
// A 6-bit field. The audio_bound is an integer in the inclusive range from 0 to 32 and is set to a value greater
|
||
// than or equal to the maximum number of ISO/IEC 13818-3 and ISO/IEC 11172-3 audio streams in the Program Stream
|
||
// for which the decoding processes are simultaneously active. For the purpose of this subclause, the decoding
|
||
// process of an ISO/IEC 13818-3 or ISO/IEC 11172-3 audio stream is active if the STD buffer is not empty or if a
|
||
// Presentation Unit is being presented in the P-STD model.
|
||
uint8_t audio_bound_;
|
||
// The CSPS_flag is a 1-bit field. If its value is set to '1' the Program Stream meets the constraints defined in
|
||
// 2.7.9.
|
||
uint8_t CSPS_flag_;
|
||
|
||
// 1B
|
||
// 1bit system_audio_lock_flag
|
||
// 1bit system_video_lock_flag
|
||
// 1bit marker_bit '1'
|
||
// 5bits video_bound
|
||
// The system_audio_lock_flag is a 1-bit field indicating that there is a specified, constant rational relationship
|
||
// between the audio sampling rate and the system_clock_frequency in the system target decoder. The
|
||
// system_clock_frequency is defined in 2.5.2.1 and the audio sampling rate is specified in ISO/IEC 13818-3. The
|
||
// system_audio_lock_flag may only be set to '1' if, for all presentation units in all audio elementary streams in
|
||
// the Program Stream, the ratio of system_clock_frequency to the actual audio sampling rate, SCASR, is constant and
|
||
// equal to the value indicated in the following table at the nominal sampling rate indicated in the audio stream.
|
||
uint8_t system_audio_lock_flag_;
|
||
// The system_video_lock_flag is a 1-bit field indicating that there is a specified, constant rational relationship
|
||
// between the video frame rate and the system clock frequency in the system target decoder. Subclause 2.5.2.1
|
||
// defines system_clock_frequency and the video frame rate is specified in ITU-T Rec. H.262 | ISO/IEC 13818-2. The
|
||
// system_video_lock_flag may only be set to '1' if, for all presentation units in all video elementary streams in
|
||
// the ITU-T Rec. H.222.0 | ISO/IEC 13818-1 program, the ratio of system_clock_frequency to the actual video frame
|
||
// rate, SCFR, is constant and equal to the value indicated in the following table at the nominal frame rate
|
||
// indicated in the video stream.
|
||
uint8_t system_video_lock_flag_;
|
||
// The video_bound is a 5-bit integer in the inclusive range from 0 to 16 and is set to a value greater than or
|
||
// equal to the maximum number of ITU-T Rec. H.262 | ISO/IEC 13818-2 and ISO/IEC 11172-2 streams in the Program
|
||
// Stream of which the decoding processes are simultaneously active. For the purpose of this subclause, the decoding
|
||
// process of an ITU-T Rec. H.262 | ISO/IEC 13818-2 and ISO/IEC 11172-2 video stream is active if the P-STD buffer
|
||
// is not empty, or if a Presentation Unit is being presented in the P-STD model, or if the reorder buffer is not
|
||
// empty.
|
||
uint8_t video_bound_;
|
||
|
||
// 1B
|
||
// 1bit packet_rate_restriction_flag
|
||
// 5bits reserved_bits
|
||
// The packet_rate_restriction_flag is a 1-bit flag. If the CSPS flag is set to '1', the
|
||
// packet_rate_restriction_flag indicates which constraint is applicable to the packet rate, as specified in 2.7.9.
|
||
// If the CSPS flag is set to value of '0', then the meaning of the packet_rate_restriction_flag is undefined.
|
||
uint8_t packet_rate_restriction_flag_;
|
||
|
||
// 3B
|
||
// 8bits stream_id
|
||
// 2bits fixed '11'
|
||
// 1bit buffer_bound_scale
|
||
// 13bits buffer_size_bound
|
||
// Has some audio or video stream, by the next bit is 1.
|
||
// Note that we ignore other streams except audio and video.
|
||
//
|
||
// The stream_id is an 8-bit field that indicates the coding and elementary stream number of the stream to which the
|
||
// following P-STD_buffer_bound_scale and P-STD_buffer_size_bound fields refer.
|
||
// If stream_id equals '1011 1000' the P-STD_buffer_bound_scale and P-STD_buffer_size_bound fields following the
|
||
// stream_id refer to all audio streams in the Program Stream.
|
||
// If stream_id equals '1011 1001' the P-STD_buffer_bound_scale and P-STD_buffer_size_bound fields following the
|
||
// stream_id refer to all video streams in the Program Stream.
|
||
// If the stream_id takes on any other value it shall be a byte value greater than or equal to '1011 1100' and shall
|
||
// be interpreted as referring to the stream coding and elementary stream number according to Table 2-18.
|
||
//
|
||
uint8_t audio_stream_id_;
|
||
uint8_t audio_buffer_bound_scale_;
|
||
uint16_t audio_buffer_size_bound_;
|
||
//
|
||
uint8_t video_stream_id_;
|
||
uint8_t video_buffer_bound_scale_;
|
||
uint16_t video_buffer_size_bound_;
|
||
public:
|
||
SrsPsPacket(SrsPsContext* context);
|
||
virtual ~SrsPsPacket();
|
||
public:
|
||
virtual srs_error_t decode(SrsBuffer* stream);
|
||
private:
|
||
virtual srs_error_t decode_pack(SrsBuffer* stream);
|
||
virtual srs_error_t decode_system(SrsBuffer* stream);
|
||
};
|
||
|
||
// The Program Stream Map (PSM) provides a description of the elementary streams in the Program Stream and their
|
||
// relationship to one another.
|
||
// 2.5.4 Program Stream map, hls-mpeg-ts-iso13818-1.pdf, page 77
|
||
class SrsPsPsmPacket
|
||
{
|
||
public:
|
||
// 2B
|
||
// 1bit current_next_indicator
|
||
// 2bits reserved
|
||
// 5bits program_stream_map_version
|
||
// 7bits reserved
|
||
// 1bit marker_bit '1'
|
||
// This is a 1-bit field, when set to '1' indicates that the Program Stream Map sent is currently applicable. When
|
||
// the bit is set to '0', it indicates that the Program Stream Map sent is not yet applicable and shall be the next
|
||
// table to become valid.
|
||
uint8_t current_next_indicator_;
|
||
// This 5-bit field is the version number of the whole Program Stream Map. The version number shall be incremented
|
||
// by 1 modulo 32 whenever the definition of the Program Stream Map changes. When the current_next_indicator is set
|
||
// to '1', then the program_stream_map_version shall be that of the currently applicable Program Stream Map. When
|
||
// the current_next_indicator is set to '0', then the program_stream_map_version shall be that of the next
|
||
// applicable Program Stream Map.
|
||
uint8_t program_stream_map_version_;
|
||
|
||
// 2B + [program_stream_info_length_]B
|
||
// The program_stream_info_length is a 16-bit field indicating the total length of the descriptors immediately
|
||
// following this field.
|
||
uint16_t program_stream_info_length_;
|
||
|
||
// 2B
|
||
// This is a 16-bit field specifying the total length, in bytes, of all elementary stream information in this
|
||
// program stream map. It includes the stream_type, elementary_stream_id, and elementary_stream_info_length fields.
|
||
uint16_t elementary_stream_map_length_;
|
||
|
||
// 4B + [elementary_stream_info_length_]B
|
||
// 8bits stream_type
|
||
// 8bits elementary_stream_id
|
||
// 16bits elementary_stream_info_length
|
||
// This 8-bit field specifies the type of the stream according to Table 2-29. The stream_type field shall only
|
||
// identify elementary streams contained in PES packets. A value of 0x05 is prohibited.
|
||
// The elementary_stream_id is an 8-bit field indicating the value of the stream_id field in the PES packet headers
|
||
// of PES packets in which this elementary stream is stored.
|
||
// The elementary_stream_info_length is a 16-bit field indicating the length in bytes of the descriptors immediately
|
||
// following this field.
|
||
// Definition for the descriptor() fields may be found in 2.6.
|
||
//
|
||
uint8_t video_stream_type_;
|
||
uint8_t video_elementary_stream_id_;
|
||
uint16_t video_elementary_stream_info_length_;
|
||
//
|
||
uint8_t audio_stream_type_;
|
||
uint8_t audio_elementary_stream_id_;
|
||
uint16_t audio_elementary_stream_info_length_;
|
||
|
||
// 4B
|
||
// This is a 32-bit field that contains the CRC value that gives a zero output of the registers in the decoder
|
||
// defined in Annex A after processing the entire program stream map.
|
||
uint32_t CRC_32_;
|
||
public:
|
||
SrsPsPsmPacket();
|
||
virtual ~SrsPsPsmPacket();
|
||
public:
|
||
virtual srs_error_t decode(SrsBuffer* stream);
|
||
};
|
||
|
||
#endif
|
||
|