Skip to content

Commit

Permalink
for ossrs#250, add comments for elemetary stream specifed by stream_id.
Browse files Browse the repository at this point in the history
  • Loading branch information
winlinvip committed Jan 31, 2015
1 parent a384cc4 commit bce78fd
Show file tree
Hide file tree
Showing 3 changed files with 191 additions and 69 deletions.
82 changes: 79 additions & 3 deletions trunk/src/app/srs_app_mpegts_udp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ using namespace std;
#include <srs_kernel_stream.hpp>
#include <srs_kernel_ts.hpp>
#include <srs_kernel_buffer.hpp>
#include <srs_kernel_file.hpp>
#include <srs_core_autofree.hpp>

#ifdef SRS_AUTO_STREAM_CASTER

Expand Down Expand Up @@ -72,6 +74,39 @@ int SrsMpegtsOverUdp::on_udp_packet(sockaddr_in* from, char* buf, int nb_buf)
// append to buffer.
buffer->append(buf, nb_buf);

srs_info("udp: got %s:%d packet %d/%d bytes",
peer_ip.c_str(), peer_port, nb_buf, buffer->length());

// collect nMB data to parse in a time.
// TODO: FIXME: comment the following for release.
//if (buffer->length() < 3 * 1024 * 1024) return ret;
// TODO: FIXME: remove the debug to file.
#if 0
SrsFileWriter fw;
if ((ret = fw.open("latest.ts")) != ERROR_SUCCESS) {
return ret;
}
if ((ret = fw.write(buffer->bytes(), buffer->length(), NULL)) != ERROR_SUCCESS) {
return ret;
}
fw.close();
#endif
#if 0
SrsFileReader fr;
if ((ret = fr.open("latest.ts")) != ERROR_SUCCESS) {
return ret;
}
buffer->erase(buffer->length());
int nb_fbuf = fr.filesize();
char* fbuf = new char[nb_fbuf];
SrsAutoFree(char, fbuf);
if ((ret = fr.read(fbuf, nb_fbuf, NULL)) != ERROR_SUCCESS) {
return ret;
}
fr.close();
buffer->append(fbuf, nb_fbuf);
#endif

// find the sync byte of mpegts.
char* p = buffer->bytes();
for (int i = 0; i < buffer->length(); i++) {
Expand All @@ -87,12 +122,10 @@ int SrsMpegtsOverUdp::on_udp_packet(sockaddr_in* from, char* buf, int nb_buf)

// drop ts packet when size not modulus by 188
if (buffer->length() < SRS_TS_PACKET_SIZE) {
srs_info("udp: wait %s:%d packet %d/%d bytes",
srs_warn("udp: wait %s:%d packet %d/%d bytes",
peer_ip.c_str(), peer_port, nb_buf, buffer->length());
return ret;
}
srs_info("udp: got %s:%d packet %d/%d bytes",
peer_ip.c_str(), peer_port, nb_buf, buffer->length());

// use stream to parse ts packet.
int nb_packet = buffer->length() / SRS_TS_PACKET_SIZE;
Expand Down Expand Up @@ -122,6 +155,49 @@ int SrsMpegtsOverUdp::on_udp_packet(sockaddr_in* from, char* buf, int nb_buf)
int SrsMpegtsOverUdp::on_ts_message(SrsTsMessage* msg)
{
int ret = ERROR_SUCCESS;

// about the bytes of msg, specified by elementary stream which indicates by PES_packet_data_byte and stream_id
// for example, when SrsTsStream of SrsTsChannel indicates stream_type is SrsTsStreamVideoMpeg4 and SrsTsStreamAudioMpeg4,
// the elementary stream can be mux in "2.11 Carriage of ISO/IEC 14496 data" in hls-mpeg-ts-iso13818-1.pdf, page 103
// @remark, the most popular stream_id is 0xe0 for h.264 over mpegts, which indicates the stream_id is video and
// stream_number is 0, where I guess the elementary is specified in 13818-2(video part).
// because when audio stream_number is 0, the elementary is ADTS specified in 13818-7(aac part).

// about the bytes of PES_packet_data_byte, defined in hls-mpeg-ts-iso13818-1.pdf, page 58
// PES_packet_data_byte ¨C PES_packet_data_bytes shall be contiguous bytes of data from the elementary stream
// indicated by the packet¡¯s stream_id or PID. When the elementary stream data conforms to ITU-T
// Rec. H.262 | ISO/IEC 13818-2 or ISO/IEC 13818-3, the PES_packet_data_bytes shall be byte aligned to the bytes of this
// Recommendation | International Standard. The byte-order of the elementary stream shall be preserved. The number of
// PES_packet_data_bytes, N, is specified by the PES_packet_length field. N shall be equal to the value indicated in the
// PES_packet_length minus the number of bytes between the last byte of the PES_packet_length field and the first
// PES_packet_data_byte.
//
// In the case of a private_stream_1, private_stream_2, ECM_stream, or EMM_stream, the contents of the
// PES_packet_data_byte field are user definable and will not be specified by ITU-T | ISO/IEC in the future.

// about the bytes of stream_id, define in hls-mpeg-ts-iso13818-1.pdf, page 49
// stream_id ¨C In Program Streams, the stream_id specifies the type and number of the elementary stream as defined by the
// stream_id Table 2-18. In Transport Streams, the stream_id may be set to any valid value which correctly describes the
// elementary stream type as defined in Table 2-18. In Transport Streams, the elementary stream type is specified in the
// Program Specific Information as specified in 2.4.4.

// about the stream_id table, define in Table 2-18 ¨C Stream_id assignments, hls-mpeg-ts-iso13818-1.pdf, page 52.
//
// 110x xxxx
// ISO/IEC 13818-3 or ISO/IEC 11172-3 or ISO/IEC 13818-7 or ISO/IEC
// 14496-3 audio stream number x xxxx
// ((sid >> 5) & 0x07) == SrsTsPESStreamIdAudio
//
// 1110 xxxx
// ITU-T Rec. H.262 | ISO/IEC 13818-2 or ISO/IEC 11172-2 or ISO/IEC
// 14496-2 video stream number xxxx
// ((stream_id >> 4) & 0x0f) == SrsTsPESStreamIdVideo

srs_trace("mpegts: got %s dts=%"PRId64", pts=%"PRId64", size=%d, us=%d, cc=%d, sid=%#x(%s-%d)",
(msg->channel->apply == SrsTsPidApplyVideo)? "Video":"Audio", msg->dts, msg->pts, msg->payload->length(),
msg->packet->payload_unit_start_indicator, msg->continuity_counter, msg->sid,
msg->is_audio()? "A":msg->is_video()? "V":"N", msg->stream_number());

// TODO: FIXME: implements it.
return ret;
}
Expand Down
40 changes: 32 additions & 8 deletions trunk/src/kernel/srs_kernel_ts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,7 @@ SrsTsMessage::SrsTsMessage(SrsTsChannel* c, SrsTsPacket* p)
packet = p;

dts = pts = 0;
sid = (SrsTsPESStreamId)0x00;
continuity_counter = 0;
PES_packet_length = 0;
payload = new SrsSimpleBuffer();
Expand Down Expand Up @@ -474,6 +475,26 @@ bool SrsTsMessage::fresh()
return payload->length() == 0;
}

bool SrsTsMessage::is_audio()
{
return ((sid >> 5) & 0x07) == SrsTsPESStreamIdAudio;
}

bool SrsTsMessage::is_video()
{
return ((sid >> 4) & 0x0f) == SrsTsPESStreamIdVideo;
}

int SrsTsMessage::stream_number()
{
if (is_audio()) {
return sid & 0x1f;
} else if (is_video()) {
return sid & 0x0f;
}
return -1;
}

ISrsTsHandler::ISrsTsHandler()
{
}
Expand Down Expand Up @@ -945,21 +966,22 @@ int SrsTsPayloadPES::decode(SrsStream* stream, SrsTsMessage** ppmsg)
// should be 1 for the fresh msg.
if (msg->fresh() && !packet->payload_unit_start_indicator) {
ret = ERROR_STREAM_CASTER_TS_PSE;
srs_error("ts: PES fresh packet length=%d, unit_start=%d. ret=%d",
msg->PES_packet_length, packet->payload_unit_start_indicator, ret);
srs_error("ts: PES fresh packet length=%d, us=%d, cc=%d. ret=%d",
msg->PES_packet_length, packet->payload_unit_start_indicator, packet->continuity_counter,
ret);
return ret;
}

// check when not fresh and PES_packet_length>0,
// the payload_unit_start_indicator should never be 1 when not completed.
if (!msg->fresh() && msg->PES_packet_length > 0
&& packet->payload_unit_start_indicator
&& !msg->completed(packet->payload_unit_start_indicator)
&& packet->payload_unit_start_indicator
) {
ret = ERROR_STREAM_CASTER_TS_PSE;
srs_error("ts: PES packet length=%d, payload=%d, unit_start=%d. ret=%d",
msg->PES_packet_length, msg->payload->length(),
packet->payload_unit_start_indicator, ret);
srs_error("ts: PES packet length=%d, payload=%d, us=%d, cc=%d. ret=%d",
msg->PES_packet_length, msg->payload->length(), packet->payload_unit_start_indicator,
packet->continuity_counter, ret);

// reparse current msg.
stream->skip(stream->pos() * -1);
Expand All @@ -975,7 +997,7 @@ int SrsTsPayloadPES::decode(SrsStream* stream, SrsTsMessage** ppmsg)
if (msg->continuity_counter >= packet->continuity_counter
&& ((msg->continuity_counter + 1) & 0x0f) > packet->continuity_counter
) {
srs_warn("ts: drop PES %dB for duplicated continuity=%#x", msg->continuity_counter);
srs_warn("ts: drop PES %dB for duplicated cc=%#x", msg->continuity_counter);
stream->skip(stream->size() - stream->pos());
return ret;
}
Expand Down Expand Up @@ -1037,8 +1059,10 @@ int SrsTsPayloadPES::decode(SrsStream* stream, SrsTsMessage** ppmsg)
}
int pos_packet = stream->pos();

// @remark SrsTsPESStreamIdAudio and SrsTsPESStreamIdVideo is not used here.
// @remark the sid indicates the elementary stream format.
// the SrsTsPESStreamIdAudio and SrsTsPESStreamIdVideo is start by 0b110 or 0b1110
SrsTsPESStreamId sid = (SrsTsPESStreamId)stream_id;
msg->sid = sid;

if (sid != SrsTsPESStreamIdProgramStreamMap
&& sid != SrsTsPESStreamIdPaddingStream
Expand Down
138 changes: 80 additions & 58 deletions trunk/src/kernel/srs_kernel_ts.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ enum SrsTsStream
// ISO/IEC 14496-2 Visual
SrsTsStreamVideoMpeg4 = 0x10,
// ISO/IEC 14496-3 Audio with the LATM transport syntax as defined in ISO/IEC 14496-3 / AMD 1
SrsTsStreamAudioMpeg4 = 0x11,
// ISO/IEC 14496-1 SL-packetized stream or FlexMux stream carried in PES packets
// ISO/IEC 14496-1 SL-packetized stream or FlexMux stream carried in ISO/IEC14496_sections.
// ISO/IEC 13818-6 Synchronized Download Protocol
Expand All @@ -188,19 +189,83 @@ struct SrsTsChannel
virtual ~SrsTsChannel();
};

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

// 110x xxxx
// ISO/IEC 13818-3 or ISO/IEC 11172-3 or ISO/IEC 13818-7 or ISO/IEC
// 14496-3 audio stream number x xxxx
// ((sid >> 5) & 0x07) == SrsTsPESStreamIdAudio
SrsTsPESStreamIdAudio = 0x06, // 0b110

// 1110 xxxx
// ITU-T Rec. H.262 | ISO/IEC 13818-2 or ISO/IEC 11172-2 or ISO/IEC
// 14496-2 video stream number xxxx
// ((stream_id >> 4) & 0x0f) == SrsTsPESStreamIdVideo
SrsTsPESStreamIdVideo = 0x0e, // 0b1110

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

/**
* the media audio/video message parsed from PES packet.
*/
class SrsTsMessage
{
private:
public:
SrsTsChannel* channel;
SrsTsPacket* packet;
public:
// the timestamp in 90khz
int64_t dts;
int64_t pts;
// the id of pes stream to indicates the payload codec.
// @remark use is_audio() and is_video() to check it, and stream_number() to finger it out.
SrsTsPESStreamId sid;
// the size of payload, 0 indicates the length() of payload.
u_int16_t PES_packet_length;
// the chunk id.
u_int8_t continuity_counter;
// the payload bytes.
SrsSimpleBuffer* payload;
public:
SrsTsMessage(SrsTsChannel* c, SrsTsPacket* p);
Expand All @@ -223,6 +288,20 @@ class SrsTsMessage
* whether the message is fresh.
*/
virtual bool fresh();
public:
/**
* whether the sid indicates the elementary stream audio.
*/
virtual bool is_audio();
/**
* whether the sid indicates the elementary stream video.
*/
virtual bool is_video();
/**
* when audio or video, get the stream number which specifies the format of stream.
* @return the stream number for audio/video; otherwise, -1.
*/
virtual int stream_number();
};

/**
Expand Down Expand Up @@ -722,63 +801,6 @@ class SrsTsPayload
virtual int decode(SrsStream* stream, SrsTsMessage** ppmsg) = 0;
};

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

// 110x xxxx
// ISO/IEC 13818-3 or ISO/IEC 11172-3 or ISO/IEC 13818-7 or ISO/IEC
// 14496-3 audio stream number x xxxx
// (stream_id>>5)&0x07 == SrsTsPESStreamIdAudio
SrsTsPESStreamIdAudio = 0x06, // 0b110

// 1110 xxxx
// ITU-T Rec. H.262 | ISO/IEC 13818-2 or ISO/IEC 11172-2 or ISO/IEC
// 14496-2 video stream number xxxx
// (stream_id>>4)&0x0f == SrsTsPESStreamIdVideo
SrsTsPESStreamIdVideo = 0x0e, // 0b1110

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

/**
* the PES payload of ts packet.
* 2.4.3.6 PES packet, hls-mpeg-ts-iso13818-1.pdf, page 49
Expand Down

0 comments on commit bce78fd

Please sign in to comment.