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
2013-11-18 23:49:18 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
a47a53f271c898403385214e355983277de28ec6
a47a53f2
1 parent
89332789
update the ts_info parse the PMT and PES header
显示空白字符变更
内嵌
并排对比
正在显示
3 个修改的文件
包含
629 行增加
和
200 行删除
trunk/conf/srs.conf
trunk/research/ts_info.cpp
trunk/src/srs/srs.upp
trunk/conf/srs.conf
查看文件 @
a47a53f
# the listen ports, split by space.
listen
193
7
;
listen
193
5
;
# the default chunk size is 128, max is 65536,
# some client does not support chunk size change,
# however, most clients supports it and it can improve
...
...
trunk/research/ts_info.cpp
查看文件 @
a47a53f
...
...
@@ -10,6 +10,8 @@ g++ -o ts_info ts_info.cpp -g -O0 -ansi
#include <string.h>
#include <assert.h>
#include <vector>
#define trace(msg, ...) printf(msg"\n", ##__VA_ARGS__);
#define srs_freep(p) delete p; p = NULL
#define srs_freepa(p) delete[] p; p = NULL
...
...
@@ -63,11 +65,65 @@ Annex A ¨C CRC Decoder Model
#define AFC_BOTH 0x03
#endif
struct
TSPacket
// Table 2-29 – Stream type assignments. page 66.
enum
TSStreamType
{
/*defined by ffmpeg*/
TSStreamTypeVideoMpeg1
=
0x01
,
TSStreamTypeVideoMpeg2
=
0x02
,
TSStreamTypeAudioMpeg1
=
0x03
,
TSStreamTypeAudioMpeg2
=
0x04
,
TSStreamTypePrivateSection
=
0x05
,
TSStreamTypePrivateData
=
0x06
,
TSStreamTypeAudioAAC
=
0x0f
,
TSStreamTypeVideoMpeg4
=
0x10
,
TSStreamTypeVideoH264
=
0x1b
,
TSStreamTypeAudioAC3
=
0x81
,
TSStreamTypeAudioDTS
=
0x8a
,
};
/**
* the actually parsed type.
*/
enum
TSPidType
{
// 4B ts packet header.
struct
Header
{
TSPidTypeReserved
=
0
,
// TSPidTypeReserved, nothing parsed, used reserved.
TSPidTypePAT
,
// Program associtate table
TSPidTypePMT
,
// Program map table.
TSPidTypeVideo
,
TSPidTypeAudio
,
};
// forward declares.
class
TSHeader
;
class
TSAdaptionField
;
class
TSPayload
;
class
TSPayloadReserved
;
class
TSPayloadPAT
;
class
TSPayloadPMT
;
class
TSPayloadPES
;
class
TSContext
;
// TSPacket declares.
class
TSPacket
{
public
:
TSHeader
*
header
;
TSAdaptionField
*
adaption_field
;
TSPayload
*
payload
;
TSPacket
();
virtual
~
TSPacket
();
int
demux
(
TSContext
*
ctx
,
u_int8_t
*
start
,
u_int8_t
*
last
,
u_int8_t
*&
p
);
int
finish
();
};
// TSHeader declares.
class
TSHeader
{
public
:
// 1B
int8_t
sync_byte
;
//8bits
// 2B
...
...
@@ -80,48 +136,16 @@ struct TSPacket
int8_t
adaption_field_control
;
//2bits
u_int8_t
continuity_counter
;
//4bits
int
get_size
()
{
return
4
;
}
int
demux
(
TSPacket
*
ppkt
,
u_int8_t
*
start
,
u_int8_t
*
last
,
u_int8_t
*&
p
)
{
int
ret
=
0
;
// ts packet header.
sync_byte
=
*
p
++
;
if
(
sync_byte
!=
0x47
)
{
trace
(
"ts+sync_bytes invalid sync_bytes: %#x, expect is 0x47"
,
sync_byte
);
return
-
1
;
}
pid
=
0
;
((
char
*
)
&
pid
)[
1
]
=
*
p
++
;
((
char
*
)
&
pid
)[
0
]
=
*
p
++
;
transport_error_indicator
=
(
pid
>>
15
)
&
0x01
;
payload_unit_start_indicator
=
(
pid
>>
14
)
&
0x01
;
transport_priority
=
(
pid
>>
13
)
&
0x01
;
pid
&=
0x1FFF
;
continuity_counter
=
*
p
++
;
transport_scrambling_control
=
(
continuity_counter
>>
6
)
&
0x03
;
adaption_field_control
=
(
continuity_counter
>>
4
)
&
0x03
;
continuity_counter
&=
0x0F
;
trace
(
"ts+header sync: %#x error: %d unit_start: %d priotiry: %d pid: %d scrambling: %d adaption: %d counter: %d"
,
sync_byte
,
transport_error_indicator
,
payload_unit_start_indicator
,
transport_priority
,
pid
,
transport_scrambling_control
,
adaption_field_control
,
continuity_counter
);
return
ret
;
}
}
*
header
;
TSHeader
();
virtual
~
TSHeader
();
int
get_size
();
int
demux
(
TSContext
*
ctx
,
TSPacket
*
pkt
,
u_int8_t
*
start
,
u_int8_t
*
last
,
u_int8_t
*&
p
);
};
// variant ts packet adation field.
struct
AdaptionField
{
// variant ts packet adation field. page 40.
class
TSAdaptionField
{
public
:
// 1B
u_int8_t
adaption_field_length
;
//8bits
// 1B
...
...
@@ -180,29 +204,288 @@ struct TSPacket
// user defined data size.
int
__user_size
;
AdaptionField
()
{
TSAdaptionField
();
virtual
~
TSAdaptionField
();
int
get_size
();
int
demux
(
TSContext
*
ctx
,
TSPacket
*
pkt
,
u_int8_t
*
start
,
u_int8_t
*
last
,
u_int8_t
*&
p
);
};
// variant ts packet payload.
// PES packet or PSI table.
// TSPayloadPAT: page 61.
class
TSPayload
{
public
:
/**
* the size of payload(payload plush the 1byte pointer_field).
*/
int
size
;
int
pointer_field_size
;
TSPidType
type
;
/**
* 2.4.4.2 Semantics definition of fields in pointer syntax
*/
u_int8_t
pointer_field
;
TSPayloadReserved
*
reserved
;
TSPayloadPAT
*
pat
;
TSPayloadPMT
*
pmt
;
TSPayloadPES
*
pes
;
/**
* 2.4.3.6 PES packet. page 49.
*/
TSPayload
();
virtual
~
TSPayload
();;
void
read_pointer_field
(
TSPacket
*
pkt
,
u_int8_t
*&
p
);
int
demux
(
TSContext
*
ctx
,
TSPacket
*
pkt
,
u_int8_t
*
start
,
u_int8_t
*
last
,
u_int8_t
*&
p
);
};
/**
* 2.4.4.3 Program association Table. page 61.
*/
class
TSPayloadPAT
{
public
:
// 1B
u_int8_t
table_id
;
//8bits
// 2B
int8_t
section_syntax_indicator
;
//1bit
int8_t
const0_value
;
//1bit
// 2bits reserved.
u_int16_t
section_length
;
//12bits
// 2B
u_int16_t
transport_stream_id
;
//16bits
// 1B
// 2bits reerverd.
int8_t
version_number
;
//5bits
int8_t
current_next_indicator
;
//1bit
// 1B
u_int8_t
section_number
;
//8bits
// 1B
u_int8_t
last_section_number
;
//8bits
// multiple 4B program data.
// program_number 16bits
// reserved 2bits
// 13bits data: 0x1FFF
// if program_number program_map_PID 13bits
// else network_PID 13bytes.
int
program_size
;
int32_t
*
programs
;
//32bits
// 4B
int32_t
CRC_32
;
//32bits
TSPayloadPAT
();
virtual
~
TSPayloadPAT
();
int
demux
(
TSContext
*
ctx
,
TSPacket
*
pkt
,
u_int8_t
*
start
,
u_int8_t
*
last
,
u_int8_t
*&
p
);
};
class
TSPMTESInfo
{
public
:
// 1B
u_int8_t
stream_type
;
//8bits
// 2B
// 3bits reserved
int16_t
elementary_PID
;
//13bits
// 2B
// 4bits reserved
int16_t
ES_info_length
;
//12bits
char
*
ES_info
;
//[ES_info_length] bytes.
TSPMTESInfo
();
virtual
~
TSPMTESInfo
();
};
/**
* 2.4.4.8 Program Map Table. page 64.
*/
class
TSPayloadPMT
{
public
:
// 1B
u_int8_t
table_id
;
//8bits
// 2B
int8_t
section_syntax_indicator
;
//1bit
int8_t
const0_value
;
//1bit
// 2bits reserved.
u_int16_t
section_length
;
//12bits
// 2B
u_int16_t
program_number
;
//16bits
// 1B
// 2bits reerverd.
int8_t
version_number
;
//5bits
int8_t
current_next_indicator
;
//1bit
// 1B
u_int8_t
section_number
;
//8bits
// 1B
u_int8_t
last_section_number
;
//8bits
// 2B
// 2bits reserved.
int16_t
PCR_PID
;
//16bits
// 2B
// 4bits reserved.
int16_t
program_info_length
;
//12bits
char
*
program_info_desc
;
//[program_info_length]bytes
// array of TSPMTESInfo.
std
::
vector
<
TSPMTESInfo
*>
ES_info
;
// 4B
int32_t
CRC_32
;
//32bits
TSPayloadPMT
();
virtual
~
TSPayloadPMT
();
int
demux
(
TSContext
*
ctx
,
TSPacket
*
pkt
,
u_int8_t
*
start
,
u_int8_t
*
last
,
u_int8_t
*&
p
);
};
/**
* 2.4.3.7 Semantic definition of fields in PES packet. page 49.
*/
class
TSPayloadPES
{
public
:
// 3B
int32_t
packet_start_code_prefix
;
//24bits
// 1B
u_int8_t
stream_id
;
//8bits
// 2B
u_int16_t
PES_packet_length
;
//16bits
TSPayloadPES
();
virtual
~
TSPayloadPES
();
int
demux
(
TSContext
*
ctx
,
TSPacket
*
pkt
,
u_int8_t
*
start
,
u_int8_t
*
last
,
u_int8_t
*&
p
);
};
class
TSPayloadReserved
{
public
:
int
size
;
char
*
bytes
;
TSPayloadReserved
();
virtual
~
TSPayloadReserved
();
int
demux
(
TSContext
*
ctx
,
TSPacket
*
pkt
,
u_int8_t
*
start
,
u_int8_t
*
last
,
u_int8_t
*&
p
);
};
struct
TSPid
{
TSPidType
type
;
int16_t
pid
;
};
// ts context
class
TSContext
{
public
:
/**
* consumed pids.
*/
int
pid_size
;
TSPid
*
pids
;
TSContext
();
virtual
~
TSContext
();
bool
exists
(
int16_t
pid
);
TSPid
*
get
(
int16_t
pid
);
void
push
(
TSPidType
type
,
int16_t
pid
);
};
TSContext
::
TSContext
()
{
pid_size
=
0
;
pids
=
NULL
;
}
TSContext
::~
TSContext
()
{
srs_freepa
(
pids
);
}
bool
TSContext
::
exists
(
int16_t
pid
)
{
for
(
int
i
=
0
;
i
<
pid_size
;
i
++
)
{
if
(
pid
==
pids
[
i
].
pid
)
{
return
true
;
}
}
return
false
;
}
TSPid
*
TSContext
::
get
(
int16_t
pid
)
{
for
(
int
i
=
0
;
i
<
pid_size
;
i
++
)
{
if
(
pid
==
pids
[
i
].
pid
)
{
return
&
pids
[
i
];
}
}
return
NULL
;
}
void
TSContext
::
push
(
TSPidType
type
,
int16_t
pid
)
{
if
(
exists
(
pid
))
{
return
;
}
TSPid
*
p
=
new
TSPid
[
pid_size
+
1
];
memcpy
(
p
,
pids
,
sizeof
(
TSPid
)
*
pid_size
);
p
[
pid_size
]
=
(
TSPid
){
type
,
pid
};
pid_size
++
;
srs_freepa
(
pids
);
pids
=
p
;
}
TSAdaptionField
::
TSAdaptionField
()
{
transport_private_data
=
NULL
;
af_ext_reserved
=
NULL
;
af_reserved
=
NULL
;
__user_size
=
0
;
}
}
virtual
~
AdaptionField
()
{
TSAdaptionField
::~
TSAdaptionField
()
{
srs_freepa
(
transport_private_data
);
srs_freepa
(
af_ext_reserved
);
srs_freepa
(
af_reserved
);
}
}
int
get_size
()
{
int
TSAdaptionField
::
get_size
()
{
return
__user_size
;
}
}
int
demux
(
TSPacket
*
ppkt
,
u_int8_t
*
start
,
u_int8_t
*
last
,
u_int8_t
*&
p
)
{
int
TSAdaptionField
::
demux
(
TSContext
*
ctx
,
TSPacket
*
pkt
,
u_int8_t
*
start
,
u_int8_t
*
last
,
u_int8_t
*&
p
)
{
int
ret
=
0
;
adaption_field_length
=
*
p
++
;
...
...
@@ -333,58 +616,24 @@ struct TSPacket
}
return
ret
;
}
}
*
adaption_field
;
// variant ts packet payload.
// PES packet or PSI table.
struct
Payload
{
/**
* the size of payload(payload plush the 1byte pointer_field).
*/
int
size
;
int
pointer_field_size
;
/**
* the actually parsed type.
*/
enum
Type
{
TypeUnknown
=-
1
,
TypeReserved
,
// TypeReserved, nothing parsed, used reserved.
TypePAT
,
//TypePAT, PAT parsed, in pat field.
}
type
;
/**
* 2.4.4.2 Semantics definition of fields in pointer syntax
*/
u_int8_t
pointer_field
;
/**
* if not parsed, store data in this field.
*/
struct
Reserved
{
int
size
;
char
*
bytes
;
}
Reserved
()
{
TSPayloadReserved
::
TSPayloadReserved
()
{
size
=
0
;
bytes
=
NULL
;
}
}
virtual
~
Reserved
()
{
TSPayloadReserved
::~
TSPayloadReserved
()
{
srs_freepa
(
bytes
);
}
}
int
demux
(
TSPacket
*
ppkt
,
u_int8_t
*
start
,
u_int8_t
*
last
,
u_int8_t
*&
p
)
{
int
TSPayloadReserved
::
demux
(
TSContext
*
ctx
,
TSPacket
*
pkt
,
u_int8_t
*
start
,
u_int8_t
*
last
,
u_int8_t
*&
p
)
{
int
ret
=
0
;
size
=
ppkt
->
payload
->
size
-
ppkt
->
payload
->
pointer_field_size
;
size
=
pkt
->
payload
->
size
-
pkt
->
payload
->
pointer_field_size
;
// not parsed bytes.
if
(
size
>
0
)
{
...
...
@@ -394,66 +643,20 @@ struct TSPacket
}
return
ret
;
}
}
*
reserved
;
/**
* 2.4.4.3 Program association Table. page 61.
*/
struct
PAT
{
// 1B
u_int8_t
table_id
;
//8bits
// 2B
int8_t
section_syntax_indicator
;
//1bit
int8_t
const0_value
;
//1bit
// 2bits reserved.
u_int16_t
section_length
;
//12bits
// 2B
u_int16_t
transport_stream_id
;
//16bits
// 1B
// 2bits reerverd.
int8_t
version_number
;
//5bits
int8_t
current_next_indicator
;
//1bit
// 1B
u_int8_t
section_number
;
//8bits
// 1B
u_int8_t
last_section_number
;
//8bits
// multiple 4B program data.
// program_number 16bits
// reserved 2bits
// 13bits data: 0x1FFF
// if program_number program_map_PID 13bits
// else network_PID 13bytes.
int
program_size
;
int32_t
*
programs
;
//32bits
// 4B
int32_t
CRC_32
;
//32bits
}
PAT
()
{
TSPayloadPAT
::
TSPayloadPAT
()
{
programs
=
NULL
;
}
}
virtual
~
PAT
()
{
TSPayloadPAT
::~
TSPayloadPAT
()
{
srs_freepa
(
programs
);
}
int
get_program
(
int
index
)
{
srs_assert
(
index
<
program_size
);
return
programs
[
index
]
&
0x1FFF
;
}
}
int
demux
(
TSPacket
*
ppkt
,
u_int8_t
*
start
,
u_int8_t
*
last
,
u_int8_t
*&
p
)
{
int
TSPayloadPAT
::
demux
(
TSContext
*
ctx
,
TSPacket
*
pkt
,
u_int8_t
*
start
,
u_int8_t
*
last
,
u_int8_t
*&
p
)
{
int
ret
=
0
;
table_id
=
*
p
++
;
...
...
@@ -489,6 +692,9 @@ struct TSPacket
pp
[
2
]
=
*
p
++
;
pp
[
1
]
=
*
p
++
;
pp
[
0
]
=
*
p
++
;
int16_t
pid
=
programs
[
i
]
&
0x1FFF
;
ctx
->
push
(
TSPidTypePMT
,
pid
);
}
}
...
...
@@ -499,79 +705,251 @@ struct TSPacket
pp
[
0
]
=
*
p
++
;
return
ret
;
}
TSPMTESInfo
::
TSPMTESInfo
()
{
ES_info_length
=
0
;
ES_info
=
NULL
;
}
TSPMTESInfo
::~
TSPMTESInfo
()
{
srs_freepa
(
ES_info
);
}
TSPayloadPMT
::
TSPayloadPMT
()
{
program_info_length
=
0
;
program_info_desc
=
NULL
;
}
TSPayloadPMT
::~
TSPayloadPMT
()
{
srs_freepa
(
program_info_desc
);
for
(
std
::
vector
<
TSPMTESInfo
*>::
iterator
it
=
ES_info
.
begin
();
it
!=
ES_info
.
end
();
++
it
)
{
TSPMTESInfo
*
info
=
*
it
;
srs_freep
(
info
);
}
}
*
pat
;
ES_info
.
clear
();
}
/**
* 2.4.3.6 PES packet. page 49.
*/
int
TSPayloadPMT
::
demux
(
TSContext
*
ctx
,
TSPacket
*
pkt
,
u_int8_t
*
start
,
u_int8_t
*
last
,
u_int8_t
*&
p
)
{
int
ret
=
0
;
table_id
=
*
p
++
;
char
*
pp
=
(
char
*
)
&
section_length
;
pp
[
1
]
=
*
p
++
;
pp
[
0
]
=
*
p
++
;
u_int8_t
*
pos
=
p
;
section_syntax_indicator
=
(
section_length
>>
15
)
&
0x01
;
const0_value
=
(
section_length
>>
14
)
&
0x01
;
section_length
&=
0x0FFF
;
pp
=
(
char
*
)
&
program_number
;
pp
[
1
]
=
*
p
++
;
pp
[
0
]
=
*
p
++
;
current_next_indicator
=
*
p
++
;
version_number
=
(
current_next_indicator
>>
1
)
&
0x1F
;
current_next_indicator
&=
0x01
;
section_number
=
*
p
++
;
last_section_number
=
*
p
++
;
pp
=
(
char
*
)
&
PCR_PID
;
pp
[
1
]
=
*
p
++
;
pp
[
0
]
=
*
p
++
;
PCR_PID
&=
0x1FFF
;
pp
=
(
char
*
)
&
program_info_length
;
pp
[
1
]
=
*
p
++
;
pp
[
0
]
=
*
p
++
;
program_info_length
&=
0xFFF
;
if
(
program_info_length
>
0
)
{
program_info_desc
=
new
char
[
program_info_length
];
memcpy
(
program_info_desc
,
p
,
program_info_length
);
p
+=
program_info_length
;
}
// [section_length] - 4(CRC) - 9B - [program_info_length]
int
ES_bytes
=
section_length
-
4
-
9
-
program_info_length
;
while
(
ES_bytes
>
0
)
{
TSPMTESInfo
*
info
=
new
TSPMTESInfo
();
info
->
stream_type
=
*
p
++
;
ES_bytes
--
;
pp
=
(
char
*
)
&
info
->
elementary_PID
;
pp
[
1
]
=
*
p
++
;
pp
[
0
]
=
*
p
++
;
ES_bytes
-=
2
;
info
->
elementary_PID
&=
0x1FFF
;
pp
=
(
char
*
)
&
info
->
ES_info_length
;
pp
[
1
]
=
*
p
++
;
pp
[
0
]
=
*
p
++
;
ES_bytes
-=
2
;
info
->
ES_info_length
&=
0x0FFF
;
if
(
info
->
ES_info_length
>
0
)
{
info
->
ES_info
=
new
char
[
info
->
ES_info_length
];
memcpy
(
info
->
ES_info
,
p
,
info
->
ES_info_length
);
p
+=
info
->
ES_info_length
;
ES_bytes
-=
info
->
ES_info_length
;
}
ES_info
.
push_back
(
info
);
// TODO: support more video type.
if
(
info
->
stream_type
==
TSStreamTypeVideoH264
)
{
ctx
->
push
(
TSPidTypeVideo
,
info
->
elementary_PID
);
}
// TODO: support more audio type.
if
(
info
->
stream_type
==
TSStreamTypeAudioAAC
)
{
ctx
->
push
(
TSPidTypeAudio
,
info
->
elementary_PID
);
}
}
pp
=
(
char
*
)
&
CRC_32
;
pp
[
3
]
=
*
p
++
;
pp
[
2
]
=
*
p
++
;
pp
[
1
]
=
*
p
++
;
pp
[
0
]
=
*
p
++
;
return
ret
;
}
TSPayloadPES
::
TSPayloadPES
()
{
}
Payload
()
{
TSPayloadPES
::~
TSPayloadPES
()
{
}
int
TSPayloadPES
::
demux
(
TSContext
*
ctx
,
TSPacket
*
pkt
,
u_int8_t
*
start
,
u_int8_t
*
last
,
u_int8_t
*&
p
)
{
int
ret
=
0
;
char
*
pp
=
(
char
*
)
&
packet_start_code_prefix
;
pp
[
2
]
=
*
p
++
;
pp
[
1
]
=
*
p
++
;
pp
[
0
]
=
*
p
++
;
packet_start_code_prefix
&=
0xFFFFFF
;
stream_id
=
*
p
++
;
pp
=
(
char
*
)
&
PES_packet_length
;
pp
[
1
]
=
*
p
++
;
pp
[
0
]
=
*
p
++
;
return
ret
;
}
/**
* 2.4.3.6 PES packet. page 49.
*/
TSPayload
::
TSPayload
()
{
size
=
0
;
pointer_field_size
=
0
;
type
=
TypeUnknown
;
type
=
TSPidTypeReserved
;
reserved
=
NULL
;
pat
=
NULL
;
}
pmt
=
NULL
;
pes
=
NULL
;
}
virtual
~
Payload
()
{
TSPayload
::~
TSPayload
()
{
srs_freep
(
reserved
);
srs_freep
(
pat
);
srs_freep
(
pmt
);
srs_freep
(
pes
);
}
void
TSPayload
::
read_pointer_field
(
TSPacket
*
pkt
,
u_int8_t
*&
p
)
{
if
(
pkt
->
header
->
payload_unit_start_indicator
)
{
pointer_field
=
*
p
++
;
pointer_field_size
=
1
;
}
}
int
demux
(
TSPacket
*
ppkt
,
u_int8_t
*
start
,
u_int8_t
*
last
,
u_int8_t
*&
p
)
{
int
TSPayload
::
demux
(
TSContext
*
ctx
,
TSPacket
*
pkt
,
u_int8_t
*
start
,
u_int8_t
*
last
,
u_int8_t
*&
p
)
{
int
ret
=
0
;
if
(
ppkt
->
header
->
payload_unit_start_indicator
)
{
pointer_field
=
*
p
++
;
pointer_field_size
=
1
;
if
(
pkt
->
header
->
pid
==
PID_PAT
)
{
read_pointer_field
(
pkt
,
p
);
type
=
TSPidTypePAT
;
pat
=
new
TSPayloadPAT
();
return
pat
->
demux
(
ctx
,
pkt
,
start
,
last
,
p
);
}
if
(
ppkt
->
header
->
pid
==
PID_PAT
)
{
type
=
TypePAT
;
pat
=
new
PAT
();
return
pat
->
demux
(
ppkt
,
start
,
last
,
p
);
TSPid
*
pid
=
ctx
->
get
(
pkt
->
header
->
pid
);
if
(
pid
&&
pid
->
type
==
TSPidTypePMT
)
{
read_pointer_field
(
pkt
,
p
);
type
=
pid
->
type
;
pmt
=
new
TSPayloadPMT
();
return
pmt
->
demux
(
ctx
,
pkt
,
start
,
last
,
p
);
}
if
(
pid
&&
(
pid
->
type
==
TSPidTypeVideo
||
pid
->
type
==
TSPidTypeAudio
))
{
type
=
pid
->
type
;
pes
=
new
TSPayloadPES
();
return
pes
->
demux
(
ctx
,
pkt
,
start
,
last
,
p
);
}
// not parsed bytes.
type
=
TypeReserved
;
reserved
=
new
Reserved
();
if
((
ret
=
reserved
->
demux
(
ppkt
,
start
,
last
,
p
))
!=
0
)
{
type
=
TSPidTypeReserved
;
reserved
=
new
TSPayloadReserved
();
if
((
ret
=
reserved
->
demux
(
ctx
,
pkt
,
start
,
last
,
p
))
!=
0
)
{
return
ret
;
}
return
ret
;
}
}
*
payload
;
}
TSPacket
()
{
header
=
new
Header
();
adaption_field
=
new
AdaptionField
();
payload
=
new
Payload
();
}
TSPacket
::
TSPacket
()
{
header
=
new
TSHeader
();
adaption_field
=
new
TSAdaptionField
();
payload
=
new
TSPayload
();
}
virtual
~
TSPacket
()
{
TSPacket
::~
TSPacket
()
{
srs_freep
(
header
);
srs_freep
(
adaption_field
);
srs_freep
(
payload
);
}
}
int
demux
(
u_int8_t
*
start
,
u_int8_t
*
last
,
u_int8_t
*&
p
)
{
int
TSPacket
::
demux
(
TSContext
*
ctx
,
u_int8_t
*
start
,
u_int8_t
*
last
,
u_int8_t
*&
p
)
{
int
ret
=
0
;
if
((
ret
=
header
->
demux
(
this
,
start
,
last
,
p
))
!=
0
)
{
if
((
ret
=
header
->
demux
(
ctx
,
this
,
start
,
last
,
p
))
!=
0
)
{
return
ret
;
}
if
(
header
->
adaption_field_control
==
AFC_ADAPTION_ONLY
||
header
->
adaption_field_control
==
AFC_BOTH
)
{
if
((
ret
=
adaption_field
->
demux
(
this
,
start
,
last
,
p
))
!=
0
)
{
if
((
ret
=
adaption_field
->
demux
(
ctx
,
this
,
start
,
last
,
p
))
!=
0
)
{
trace
(
"ts+header af(adaption field) decode error. ret=%d"
,
ret
);
return
ret
;
}
...
...
@@ -582,7 +960,7 @@ struct TSPacket
payload
->
size
=
TS_PACKET_SIZE
-
header
->
get_size
()
-
adaption_field
->
get_size
();
if
(
header
->
adaption_field_control
==
AFC_PAYLOAD_ONLY
||
header
->
adaption_field_control
==
AFC_BOTH
)
{
if
((
ret
=
payload
->
demux
(
this
,
start
,
last
,
p
))
!=
0
)
{
if
((
ret
=
payload
->
demux
(
ctx
,
this
,
start
,
last
,
p
))
!=
0
)
{
trace
(
"ts+header payload decode error. ret=%d"
,
ret
);
return
ret
;
}
...
...
@@ -594,13 +972,60 @@ struct TSPacket
payload
->
size
-
payload
->
pointer_field_size
);
return
finish
();
}
}
int
finish
()
{
int
TSPacket
::
finish
()
{
return
0
;
}
TSHeader
::
TSHeader
()
{
}
TSHeader
::~
TSHeader
()
{
}
int
TSHeader
::
get_size
()
{
return
4
;
}
int
TSHeader
::
demux
(
TSContext
*
ctx
,
TSPacket
*
pkt
,
u_int8_t
*
start
,
u_int8_t
*
last
,
u_int8_t
*&
p
)
{
int
ret
=
0
;
// ts packet header.
sync_byte
=
*
p
++
;
if
(
sync_byte
!=
0x47
)
{
trace
(
"ts+sync_bytes invalid sync_bytes: %#x, expect is 0x47"
,
sync_byte
);
return
-
1
;
}
};
pid
=
0
;
((
char
*
)
&
pid
)[
1
]
=
*
p
++
;
((
char
*
)
&
pid
)[
0
]
=
*
p
++
;
transport_error_indicator
=
(
pid
>>
15
)
&
0x01
;
payload_unit_start_indicator
=
(
pid
>>
14
)
&
0x01
;
transport_priority
=
(
pid
>>
13
)
&
0x01
;
pid
&=
0x1FFF
;
ctx
->
push
(
TSPidTypePAT
,
pid
);
continuity_counter
=
*
p
++
;
transport_scrambling_control
=
(
continuity_counter
>>
6
)
&
0x03
;
adaption_field_control
=
(
continuity_counter
>>
4
)
&
0x03
;
continuity_counter
&=
0x0F
;
trace
(
"ts+header sync: %#x error: %d unit_start: %d priotiry: %d pid: %d scrambling: %d adaption: %d counter: %d"
,
sync_byte
,
transport_error_indicator
,
payload_unit_start_indicator
,
transport_priority
,
pid
,
transport_scrambling_control
,
adaption_field_control
,
continuity_counter
);
return
ret
;
}
int
main
(
int
/*argc*/
,
char
**
/*argv*/
)
{
...
...
@@ -610,6 +1035,8 @@ int main(int /*argc*/, char** /*argv*/)
int
ret
=
0
;
trace
(
"demuxer+read packet count offset T+0 T+1 T+2 T+3 T+x T+L2 T+L1 T+L0"
);
TSContext
ctx
;
for
(
int
i
=
0
,
offset
=
0
;
;
i
++
)
{
u_int8_t
ts_packet
[
TS_PACKET_SIZE
];
memset
(
ts_packet
,
0
,
sizeof
(
ts_packet
));
...
...
@@ -632,7 +1059,7 @@ int main(int /*argc*/, char** /*argv*/)
u_int8_t
*
last
=
ts_packet
+
TS_PACKET_SIZE
;
TSPacket
pkt
;
if
((
ret
=
pkt
.
demux
(
start
,
last
,
p
))
!=
0
)
{
if
((
ret
=
pkt
.
demux
(
&
ctx
,
start
,
last
,
p
))
!=
0
)
{
trace
(
"demuxer+read decode ts packet error. ret=%d"
,
ret
);
return
ret
;
}
...
...
trunk/src/srs/srs.upp
查看文件 @
a47a53f
...
...
@@ -41,7 +41,9 @@ file
..\core\srs_core_pithy_print.hpp,
..\core\srs_core_pithy_print.cpp,
..\core\srs_core_log.hpp,
..\core\srs_core_log.cpp;
..\core\srs_core_log.cpp,
research readonly separator,
..\..\research\ts_info.cpp;
mainconfig
"" = "MAIN";
...
...
请
注册
或
登录
后发表评论