Toggle navigation
Toggle navigation
此项目
正在载入...
Sign in
胡斌
/
srs
转到一个项目
Toggle navigation
项目
群组
代码片段
帮助
Toggle navigation pinning
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
winlin
2015-01-27 18:35:43 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
cc87992fe03391ad17adab47e7badf5916a8a51a
cc87992f
1 parent
7692e50f
for #250, decode the PMT and PAT
显示空白字符变更
内嵌
并排对比
正在显示
3 个修改的文件
包含
437 行增加
和
109 行删除
trunk/src/kernel/srs_kernel_error.hpp
trunk/src/kernel/srs_kernel_ts.cpp
trunk/src/kernel/srs_kernel_ts.hpp
trunk/src/kernel/srs_kernel_error.hpp
查看文件 @
cc87992
...
...
@@ -223,6 +223,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define ERROR_STREAM_CASTER_TS_SYNC_BYTE 4013
#define ERROR_STREAM_CASTER_TS_AF 4014
#define ERROR_STREAM_CASTER_TS_CRC32 4015
#define ERROR_STREAM_CASTER_TS_PSI 4016
#define ERROR_STREAM_CASTER_TS_PAT 4017
#define ERROR_STREAM_CASTER_TS_PMT 4018
/**
* whether the error code is an system control error.
...
...
trunk/src/kernel/srs_kernel_ts.cpp
查看文件 @
cc87992
...
...
@@ -417,7 +417,7 @@ int SrsTsContext::decode(SrsStream* stream)
// parse util EOF of stream.
// for example, parse multiple times for the PES_packet_length(0) packet.
while
(
!
stream
->
empty
())
{
SrsTsPacket
*
packet
=
new
SrsTsPacket
();
SrsTsPacket
*
packet
=
new
SrsTsPacket
(
this
);
SrsAutoFree
(
SrsTsPacket
,
packet
);
if
((
ret
=
packet
->
decode
(
stream
))
!=
ERROR_SUCCESS
)
{
...
...
@@ -429,8 +429,23 @@ int SrsTsContext::decode(SrsStream* stream)
return
ret
;
}
SrsTsP
acket
::
SrsTsPacket
(
)
SrsTsP
idApply
SrsTsContext
::
get
(
int
pid
)
{
if
(
pids
.
find
(
pid
)
==
pids
.
end
())
{
return
SrsTsPidApplyReserved
;
}
return
pids
[
pid
];
}
void
SrsTsContext
::
set
(
int
pid
,
SrsTsPidApply
apply_pid
)
{
pids
[
pid
]
=
apply_pid
;
}
SrsTsPacket
::
SrsTsPacket
(
SrsTsContext
*
c
)
{
context
=
c
;
sync_byte
=
0
;
transport_error_indicator
=
0
;
payload_unit_start_indicator
=
0
;
...
...
@@ -508,9 +523,16 @@ int SrsTsPacket::decode(SrsStream* stream)
srs_freep
(
payload
);
payload
=
new
SrsTsPayloadPAT
(
this
);
}
else
{
SrsTsPidApply
apply_pid
=
context
->
get
(
pid
);
if
(
apply_pid
==
SrsTsPidApplyPMT
)
{
// 2.4.4.8 Program Map Table
srs_freep
(
payload
);
payload
=
new
SrsTsPayloadPMT
(
this
);
}
else
{
// left bytes as reserved.
stream
->
skip
(
nb_payload
);
}
}
if
(
payload
&&
(
ret
=
payload
->
decode
(
stream
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"ts: demux payload failed. ret=%d"
,
ret
);
...
...
@@ -676,6 +698,7 @@ int SrsTsAdaptationField::decode(SrsStream* stream)
}
transport_private_data_length
=
(
u_int8_t
)
stream
->
read_1bytes
();
if
(
transport_private_data_length
>
0
)
{
if
(
!
stream
->
require
(
transport_private_data_length
))
{
ret
=
ERROR_STREAM_CASTER_TS_AF
;
srs_error
(
"ts: demux af transport_private_data_flag failed. ret=%d"
,
ret
);
...
...
@@ -685,6 +708,7 @@ int SrsTsAdaptationField::decode(SrsStream* stream)
transport_private_data
=
new
char
[
transport_private_data_length
];
stream
->
read_bytes
(
transport_private_data
,
transport_private_data_length
);
}
}
if
(
adaptation_field_extension_flag
)
{
int
pos_af_ext
=
stream
->
pos
();
...
...
@@ -760,16 +784,6 @@ int SrsTsAdaptationField::decode(SrsStream* stream)
return
ret
;
}
SrsTsPayloadPATProgram
::
SrsTsPayloadPATProgram
()
{
number
=
0
;
pid
=
0
;
}
SrsTsPayloadPATProgram
::~
SrsTsPayloadPATProgram
()
{
}
SrsTsPayload
::
SrsTsPayload
(
SrsTsPacket
*
p
)
{
packet
=
p
;
...
...
@@ -782,6 +796,7 @@ SrsTsPayload::~SrsTsPayload()
SrsTsPayloadPSI
::
SrsTsPayloadPSI
(
SrsTsPacket
*
p
)
:
SrsTsPayload
(
p
)
{
pointer_field
=
0
;
CRC_32
=
0
;
}
SrsTsPayloadPSI
::~
SrsTsPayloadPSI
()
...
...
@@ -802,43 +817,21 @@ int SrsTsPayloadPSI::decode(SrsStream* stream)
*/
if
(
packet
->
payload_unit_start_indicator
)
{
if
(
!
stream
->
require
(
1
))
{
ret
=
ERROR_STREAM_CASTER_TS_
AF
;
ret
=
ERROR_STREAM_CASTER_TS_
PSI
;
srs_error
(
"ts: demux PSI failed. ret=%d"
,
ret
);
return
ret
;
}
pointer_field
=
stream
->
read_1bytes
();
}
return
ret
;
}
SrsTsPayloadPAT
::
SrsTsPayloadPAT
(
SrsTsPacket
*
p
)
:
SrsTsPayloadPSI
(
p
)
{
nb_programs
=
0
;
programs
=
NULL
;
}
SrsTsPayloadPAT
::~
SrsTsPayloadPAT
()
{
srs_freep
(
programs
);
}
int
SrsTsPayloadPAT
::
decode
(
SrsStream
*
stream
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsTsPayloadPSI
::
decode
(
stream
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
// to calc the crc32
char
*
ppat
=
stream
->
data
()
+
stream
->
pos
();
int
pat_pos
=
stream
->
pos
();
// atleast 8B without programs and crc32
if
(
!
stream
->
require
(
8
))
{
ret
=
ERROR_STREAM_CASTER_TS_AF
;
srs_error
(
"ts: demux PAT failed. ret=%d"
,
ret
);
// atleast 3B for all psi.
if
(
!
stream
->
require
(
3
))
{
ret
=
ERROR_STREAM_CASTER_TS_PSI
;
srs_error
(
"ts: demux PSI failed. ret=%d"
,
ret
);
return
ret
;
}
// 1B
...
...
@@ -851,11 +844,82 @@ int SrsTsPayloadPAT::decode(SrsStream* stream)
const0_value
=
(
section_length
>>
14
)
&
0x01
;
section_length
&=
0x0FFF
;
// no section, ignore.
if
(
section_length
==
0
)
{
srs_warn
(
"ts: demux PAT ignore empty section"
);
return
ret
;
}
if
(
!
stream
->
require
(
section_length
))
{
ret
=
ERROR_STREAM_CASTER_TS_
AF
;
ret
=
ERROR_STREAM_CASTER_TS_
PSI
;
srs_error
(
"ts: demux PAT section failed. ret=%d"
,
ret
);
return
ret
;
}
// call the virtual method of actual PSI.
if
((
ret
=
psi_decode
(
stream
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
// 4B
if
(
!
stream
->
require
(
4
))
{
ret
=
ERROR_STREAM_CASTER_TS_PSI
;
srs_error
(
"ts: demux PSI crc32 failed. ret=%d"
,
ret
);
return
ret
;
}
CRC_32
=
stream
->
read_4bytes
();
// verify crc32.
int32_t
crc32
=
srs_crc32
(
ppat
,
stream
->
pos
()
-
pat_pos
-
4
);
if
(
crc32
!=
CRC_32
)
{
ret
=
ERROR_STREAM_CASTER_TS_CRC32
;
srs_error
(
"ts: verify PSI crc32 failed. ret=%d"
,
ret
);
return
ret
;
}
// consume left stuffings
if
(
!
stream
->
empty
())
{
stream
->
skip
(
stream
->
size
()
-
stream
->
pos
());
}
return
ret
;
}
SrsTsPayloadPATProgram
::
SrsTsPayloadPATProgram
()
{
number
=
0
;
pid
=
0
;
}
SrsTsPayloadPATProgram
::~
SrsTsPayloadPATProgram
()
{
}
SrsTsPayloadPAT
::
SrsTsPayloadPAT
(
SrsTsPacket
*
p
)
:
SrsTsPayloadPSI
(
p
)
{
}
SrsTsPayloadPAT
::~
SrsTsPayloadPAT
()
{
std
::
vector
<
SrsTsPayloadPATProgram
*>::
iterator
it
;
for
(
it
=
programs
.
begin
();
it
!=
programs
.
end
();
++
it
)
{
SrsTsPayloadPATProgram
*
program
=
*
it
;
srs_freep
(
program
);
}
programs
.
clear
();
}
int
SrsTsPayloadPAT
::
psi_decode
(
SrsStream
*
stream
)
{
int
ret
=
ERROR_SUCCESS
;
// atleast 5B for PAT specified
if
(
!
stream
->
require
(
5
))
{
ret
=
ERROR_STREAM_CASTER_TS_PAT
;
srs_error
(
"ts: demux PAT failed. ret=%d"
,
ret
);
return
ret
;
}
int
pos
=
stream
->
pos
();
// 2B
...
...
@@ -876,35 +940,136 @@ int SrsTsPayloadPAT::decode(SrsStream* stream)
// multiple 4B program data.
int
program_bytes
=
section_length
-
4
-
(
stream
->
pos
()
-
pos
);
nb_programs
=
program_bytes
/
4
;
if
(
nb_programs
>
0
)
{
srs_freep
(
programs
);
programs
=
new
SrsTsPayloadPATProgram
[
nb_programs
];
for
(
int
i
=
0
;
i
<
nb_programs
;
i
++
)
{
SrsTsPayloadPATProgram
*
program
=
programs
+
i
;
for
(
int
i
=
0
;
i
<
program_bytes
;
i
+=
4
)
{
SrsTsPayloadPATProgram
*
program
=
new
SrsTsPayloadPATProgram
();
int
tmpv
=
stream
->
read_4bytes
();
program
->
number
=
(
int16_t
)((
tmpv
>>
16
)
&
0xFFFF
);
program
->
pid
=
(
int16_t
)(
tmpv
&
0x1FFF
);
// update the apply pid table.
packet
->
context
->
set
(
program
->
pid
,
SrsTsPidApplyPMT
);
programs
.
push_back
(
program
);
}
// update the apply pid table.
packet
->
context
->
set
(
packet
->
pid
,
SrsTsPidApplyPAT
);
return
ret
;
}
SrsTsPayloadPMTESInfo
::
SrsTsPayloadPMTESInfo
()
{
ES_info_length
=
0
;
ES_info
=
NULL
;
}
SrsTsPayloadPMTESInfo
::~
SrsTsPayloadPMTESInfo
()
{
srs_freep
(
ES_info
);
}
SrsTsPayloadPMT
::
SrsTsPayloadPMT
(
SrsTsPacket
*
p
)
:
SrsTsPayloadPSI
(
p
)
{
program_info_length
=
0
;
program_info_desc
=
NULL
;
}
SrsTsPayloadPMT
::~
SrsTsPayloadPMT
()
{
srs_freep
(
program_info_desc
);
std
::
vector
<
SrsTsPayloadPMTESInfo
*>::
iterator
it
;
for
(
it
=
infos
.
begin
();
it
!=
infos
.
end
();
++
it
)
{
SrsTsPayloadPMTESInfo
*
info
=
*
it
;
srs_freep
(
info
);
}
infos
.
clear
();
}
// 4B
if
(
!
stream
->
require
(
4
))
{
ret
=
ERROR_STREAM_CASTER_TS_AF
;
srs_error
(
"ts: demux PAT crc32 failed. ret=%d"
,
ret
);
int
SrsTsPayloadPMT
::
psi_decode
(
SrsStream
*
stream
)
{
int
ret
=
ERROR_SUCCESS
;
// atleast 9B for PMT specified
if
(
!
stream
->
require
(
9
))
{
ret
=
ERROR_STREAM_CASTER_TS_PMT
;
srs_error
(
"ts: demux PMT failed. ret=%d"
,
ret
);
return
ret
;
}
CRC_32
=
stream
->
read_4bytes
();
// verify crc32.
int32_t
crc32
=
srs_crc32
(
ppat
,
stream
->
pos
()
-
pat_pos
-
4
);
if
(
crc32
!=
CRC_32
)
{
ret
=
ERROR_STREAM_CASTER_TS_CRC32
;
srs_error
(
"ts: verify PAT crc32 failed. ret=%d"
,
ret
);
// 2B
program_number
=
stream
->
read_2bytes
();
// 1B
current_next_indicator
=
stream
->
read_1bytes
();
version_number
=
(
current_next_indicator
>>
1
)
&
0x1F
;
current_next_indicator
&=
0x01
;
// 1B
section_number
=
stream
->
read_1bytes
();
// 1B
last_section_number
=
stream
->
read_1bytes
();
// 2B
PCR_PID
=
stream
->
read_2bytes
();
PCR_PID
&=
0x1FFF
;
// 2B
program_info_length
=
stream
->
read_2bytes
();
program_info_length
&=
0xFFF
;
if
(
program_info_length
>
0
)
{
if
(
!
stream
->
require
(
program_info_length
))
{
ret
=
ERROR_STREAM_CASTER_TS_PMT
;
srs_error
(
"ts: demux PMT program info failed. ret=%d"
,
ret
);
return
ret
;
}
srs_freep
(
program_info_desc
);
program_info_desc
=
new
char
[
program_info_length
];
stream
->
read_bytes
(
program_info_desc
,
program_info_length
);
}
// [section_length] - 4(CRC) - 9B - [program_info_length]
int
ES_EOF_pos
=
stream
->
pos
()
+
section_length
-
4
-
9
-
program_info_length
;
while
(
stream
->
pos
()
<
ES_EOF_pos
)
{
SrsTsPayloadPMTESInfo
*
info
=
new
SrsTsPayloadPMTESInfo
();
infos
.
push_back
(
info
);
// 5B
if
(
!
stream
->
require
(
5
))
{
ret
=
ERROR_STREAM_CASTER_TS_PMT
;
srs_error
(
"ts: demux PMT es info failed. ret=%d"
,
ret
);
return
ret
;
}
info
->
stream_type
=
stream
->
read_1bytes
();
info
->
elementary_PID
=
stream
->
read_2bytes
();
info
->
ES_info_length
=
stream
->
read_2bytes
();
info
->
elementary_PID
&=
0x1FFF
;
info
->
ES_info_length
&=
0x0FFF
;
if
(
info
->
ES_info_length
>
0
)
{
if
(
!
stream
->
require
(
info
->
ES_info_length
))
{
ret
=
ERROR_STREAM_CASTER_TS_PMT
;
srs_error
(
"ts: demux PMT es info data failed. ret=%d"
,
ret
);
return
ret
;
}
srs_freep
(
info
->
ES_info
);
info
->
ES_info
=
new
char
[
info
->
ES_info_length
];
stream
->
read_bytes
(
info
->
ES_info
,
info
->
ES_info_length
);
}
}
// update the apply pid table.
packet
->
context
->
set
(
packet
->
pid
,
SrsTsPidApplyPMT
);
return
ret
;
}
...
...
trunk/src/kernel/srs_kernel_ts.hpp
查看文件 @
cc87992
...
...
@@ -30,6 +30,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <srs_core.hpp>
#include <string>
#include <map>
#include <vector>
#include <srs_kernel_codec.hpp>
...
...
@@ -64,6 +66,7 @@ public:
/**
* the pid of ts packet,
* Table 2-3 ¨C PID table, hls-mpeg-ts-iso13818-1.pdf, page 37
* NOTE ¨C The transport packets with PID values 0x0000, 0x0001, and 0x0010-0x1FFE are allowed to carry a PCR.
*/
enum
SrsTsPid
{
...
...
@@ -73,6 +76,12 @@ enum SrsTsPid
SrsTsPidCAT
=
0x01
,
// Transport Stream Description Table
SrsTsPidTSDT
=
0x02
,
// Reserved
SrsTsPidReservedStart
=
0x03
,
SrsTsPidReservedEnd
=
0x0f
,
// May be assigned as network_PID, Program_map_PID, elementary_PID, or for other purposes
SrsTsPidAppStart
=
0x10
,
SrsTsPidAppEnd
=
0x1ffe
,
// null packets (see Table 2-3)
SrsTsPidNULL
=
0x01FFF
,
};
...
...
@@ -110,10 +119,27 @@ enum SrsTsAdaptationFieldType
};
/**
* the actually parsed ts pid,
* @see SrsTsPid, some pid, for example, PMT/Video/Audio is specified by PAT or other tables.
*/
enum
SrsTsPidApply
{
SrsTsPidApplyReserved
=
0
,
// TSPidTypeReserved, nothing parsed, used reserved.
SrsTsPidApplyPAT
,
// Program associtate table
SrsTsPidApplyPMT
,
// Program map table.
SrsTsPidApplyVideo
,
// for video
SrsTsPidApplyAudio
,
// vor audio
};
/**
* the context of ts, to decode the ts stream.
*/
class
SrsTsContext
{
private
:
std
::
map
<
int
,
SrsTsPidApply
>
pids
;
public
:
SrsTsContext
();
virtual
~
SrsTsContext
();
...
...
@@ -123,6 +149,16 @@ public:
* @remark we will consume all bytes in stream.
*/
virtual
int
decode
(
SrsStream
*
stream
);
public
:
/**
* get the pid apply, the parsed pid.
* @return the apply pid; SrsTsPidApplyReserved for invalid.
*/
virtual
SrsTsPidApply
get
(
int
pid
);
/**
* set the pid apply, the parsed pid.
*/
virtual
void
set
(
int
pid
,
SrsTsPidApply
apply_pid
);
};
/**
...
...
@@ -204,7 +240,7 @@ public:
/**
* The continuity_counter is a 4-bit field incrementing with each Transport Stream packet with the
* same PID. The continuity_counter wraps around to 0 after its maximum value. The continuity_counter shall not be
*
incremented when the adaptation_field_control of the packet equals '00' or '10'
.
*
incremented when the adaptation_field_control of the packet equals '00'(reseverd) or '10'(adaptation field only)
.
*
* In Transport Streams, duplicate packets may be sent as two, and only two, consecutive Transport Stream packets of the
* same PID. The duplicate packets shall have the same continuity_counter value as the original packet and the
...
...
@@ -222,7 +258,9 @@ private:
SrsTsAdaptationField
*
adaptation_field
;
SrsTsPayload
*
payload
;
public
:
SrsTsPacket
();
SrsTsContext
*
context
;
public
:
SrsTsPacket
(
SrsTsContext
*
c
);
virtual
~
SrsTsPacket
();
public
:
virtual
int
decode
(
SrsStream
*
stream
);
...
...
@@ -561,34 +599,6 @@ enum SrsTsPsiId
};
/**
* the program of PAT of PSI ts packet.
*/
class
SrsTsPayloadPATProgram
{
public
:
// 4B
/**
* Program_number is a 16-bit field. It specifies the program to which the program_map_PID is
* applicable. When set to 0x0000, then the following PID reference shall be the network PID. For all other cases the value
* of this field is user defined. This field shall not take any single value more than once within one version of the Program
* Association Table.
*/
int16_t
number
;
// 16bits
// reserved 3bits
/**
* program_map_PID/network_PID 13bits
* network_PID ¨C The network_PID is a 13-bit field, which is used only in conjunction with the value of the
* program_number set to 0x0000, specifies the PID of the Transport Stream packets which shall contain the Network
* Information Table. The value of the network_PID field is defined by the user, but shall only take values as specified in
* Table 2-3. The presence of the network_PID is optional.
*/
int16_t
pid
;
public
:
SrsTsPayloadPATProgram
();
virtual
~
SrsTsPayloadPATProgram
();
};
/**
* the payload of ts packet, can be PES or PSI payload.
*/
class
SrsTsPayload
...
...
@@ -621,22 +631,6 @@ public:
*/
int8_t
pointer_field
;
public
:
SrsTsPayloadPSI
(
SrsTsPacket
*
p
);
virtual
~
SrsTsPayloadPSI
();
public
:
virtual
int
decode
(
SrsStream
*
stream
);
};
/**
* the PAT payload of PSI ts packet.
* 2.4.4.3 Program association Table, hls-mpeg-ts-iso13818-1.pdf, page 61
* The Program Association Table provides the correspondence between a program_number and the PID value of the
* Transport Stream packets which carry the program definition. The program_number is the numeric label associated with
* a program.
*/
class
SrsTsPayloadPAT
:
public
SrsTsPayloadPSI
{
public
:
// 1B
/**
* This is an 8-bit field, which shall be set to 0x00 as shown in Table 2-26.
...
...
@@ -659,7 +653,61 @@ public:
* field shall not exceed 1021 (0x3FD).
*/
u_int16_t
section_length
;
//12bits
public:
// 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 section.
* @remark crc32(bytes without pointer field, before crc32 field)
*/
int32_t
CRC_32
;
//32bits
public:
SrsTsPayloadPSI
(
SrsTsPacket
*
p
);
virtual
~
SrsTsPayloadPSI
();
public
:
virtual
int
decode
(
SrsStream
*
stream
);
protected
:
virtual
int
psi_decode
(
SrsStream
*
stream
)
=
0
;
};
/**
* the program of PAT of PSI ts packet.
*/
class
SrsTsPayloadPATProgram
{
public
:
// 4B
/**
* Program_number is a 16-bit field. It specifies the program to which the program_map_PID is
* applicable. When set to 0x0000, then the following PID reference shall be the network PID. For all other cases the value
* of this field is user defined. This field shall not take any single value more than once within one version of the Program
* Association Table.
*/
int16_t
number
;
// 16bits
// reserved 3bits
/**
* program_map_PID/network_PID 13bits
* network_PID ¨C The network_PID is a 13-bit field, which is used only in conjunction with the value of the
* program_number set to 0x0000, specifies the PID of the Transport Stream packets which shall contain the Network
* Information Table. The value of the network_PID field is defined by the user, but shall only take values as specified in
* Table 2-3. The presence of the network_PID is optional.
*/
int16_t
pid
;
public
:
SrsTsPayloadPATProgram
();
virtual
~
SrsTsPayloadPATProgram
();
};
/**
* the PAT payload of PSI ts packet.
* 2.4.4.3 Program association Table, hls-mpeg-ts-iso13818-1.pdf, page 61
* The Program Association Table provides the correspondence between a program_number and the PID value of the
* Transport Stream packets which carry the program definition. The program_number is the numeric label associated with
* a program.
*/
class
SrsTsPayloadPAT
:
public
SrsTsPayloadPSI
{
public
:
// 2B
/**
* This is a 16-bit field which serves as a label to identify this Transport Stream from any other
...
...
@@ -700,16 +748,128 @@ public:
u_int8_t
last_section_number
;
//8bits
// multiple 4B program data.
int
nb_programs
;
SrsTsPayloadPATProgram
*
programs
;
// 4B
int32_t
CRC_32
;
//32bits
std
::
vector
<
SrsTsPayloadPATProgram
*>
programs
;
public
:
SrsTsPayloadPAT
(
SrsTsPacket
*
p
);
virtual
~
SrsTsPayloadPAT
();
public
:
virtual
int
decode
(
SrsStream
*
stream
);
virtual
int
psi_decode
(
SrsStream
*
stream
);
};
/**
* the esinfo for PMT program.
*/
class
SrsTsPayloadPMTESInfo
{
public
:
// 1B
/**
* This is an 8-bit field specifying the type of program element carried within the packets with the PID
* whose value is specified by the elementary_PID. The values of stream_type are specified in Table 2-29.
*/
u_int8_t
stream_type
;
//8bits
// 2B
// 3bits reserved
/**
* This is a 13-bit field specifying the PID of the Transport Stream packets which carry the associated
* program element.
*/
int16_t
elementary_PID
;
//13bits
// 2B
// 4bits reserved
/**
* This is a 12-bit field, the first two bits of which shall be '00'. The remaining 10 bits specify the number
* of bytes of the descriptors of the associated program element immediately following the ES_info_length field.
*/
int16_t
ES_info_length
;
//12bits
char
*
ES_info
;
//[ES_info_length] bytes.
public:
SrsTsPayloadPMTESInfo
();
virtual
~
SrsTsPayloadPMTESInfo
();
};
/**
* the PMT payload of PSI ts packet.
* 2.4.4.8 Program Map Table, hls-mpeg-ts-iso13818-1.pdf, page 64
* The Program Map Table provides the mappings between program numbers and the program elements that comprise
* them. A single instance of such a mapping is referred to as a "program definition". The program map table is the
* complete collection of all program definitions for a Transport Stream. This table shall be transmitted in packets, the PID
* values of which are selected by the encoder. More than one PID value may be used, if desired. The table is contained in
* one or more sections with the following syntax. It may be segmented to occupy multiple sections. In each section, the
* section number field shall be set to zero. Sections are identified by the program_number field.
*/
class
SrsTsPayloadPMT
:
public
SrsTsPayloadPSI
{
public
:
// 2B
/**
* program_number is a 16-bit field. It specifies the program to which the program_map_PID is
* applicable. One program definition shall be carried within only one TS_program_map_section. This implies that a
* program definition is never longer than 1016 (0x3F8). See Informative Annex C for ways to deal with the cases when
* that length is not sufficient. The program_number may be used as a designation for a broadcast channel, for example. By
* describing the different program elements belonging to a program, data from different sources (e.g. sequential events)
* can be concatenated together to form a continuous set of streams using a program_number. For examples of applications
* refer to Annex C.
*/
u_int16_t
program_number
;
//16bits
// 1B
// 2bits reerverd.
/**
* This 5-bit field is the version number of the TS_program_map_section. The version number shall be
* incremented by 1 modulo 32 when a change in the information carried within the section occurs. Version number refers
* to the definition of a single program, and therefore to a single section. When the current_next_indicator is set to '1', then
* the version_number shall be that of the currently applicable TS_program_map_section. When the current_next_indicator
* is set to '0', then the version_number shall be that of the next applicable TS_program_map_section.
*/
int8_t
version_number
;
//5bits
/**
* A 1-bit field, which when set to '1' indicates that the TS_program_map_section sent is
* currently applicable. When the bit is set to '0', it indicates that the TS_program_map_section sent is not yet applicable
* and shall be the next TS_program_map_section to become valid.
*/
int8_t
current_next_indicator
;
//1bit
// 1B
/**
* The value of this 8-bit field shall be 0x00.
*/
u_int8_t
section_number
;
//8bits
// 1B
/**
* The value of this 8-bit field shall be 0x00.
*/
u_int8_t
last_section_number
;
//8bits
// 2B
// 2bits reserved.
/**
* This is a 13-bit field indicating the PID of the Transport Stream packets which shall contain the PCR fields
* valid for the program specified by program_number. If no PCR is associated with a program definition for private
* 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
* for restrictions on the choice of PCR_PID value.
*/
int16_t
PCR_PID
;
//16bits
// 2B
// 4bits reserved.
/**
* This is a 12-bit field, the first two bits of which shall be '00'. The remaining 10 bits specify the
* number of bytes of the descriptors immediately following the program_info_length field.
*/
u_int16_t
program_info_length
;
//12bits
char
*
program_info_desc
;
//[program_info_length]bytes
// array of TSPMTESInfo.
std
::
vector
<
SrsTsPayloadPMTESInfo
*>
infos
;
public
:
SrsTsPayloadPMT
(
SrsTsPacket
*
p
);
virtual
~
SrsTsPayloadPMT
();
public
:
virtual
int
psi_decode
(
SrsStream
*
stream
);
};
/**
...
...
请
注册
或
登录
后发表评论