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-21 22:33:32 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
a0ecc5a305ba9591e7e4662b59e80c294de94fb2
a0ecc5a3
1 parent
dc7f2cff
finger out the PES_packet_length is 0
隐藏空白字符变更
内嵌
并排对比
正在显示
2 个修改的文件
包含
276 行增加
和
147 行删除
trunk/doc/ts-audio-video-analysis.txt
trunk/research/ts_info.cpp
trunk/doc/ts-audio-video-analysis.txt
查看文件 @
a0ecc5a
...
...
@@ -228,52 +228,114 @@ TS的第二个视频包数据如下:
3031个ts包是空包,解析有问题:
47 41 00 38 07 50 05 09 5A A6 7E 00 00 00 01 E0
00 00 80 C0 0A 31 28 53 60 81 11 28 53 42 F9 00
00 00 01 09 F0 00 00 00 01 67 64 00 28 AC D1 C0
50 05 BB FF 00 2D 00 22 10 00 00 03 00 10 00 00
03 03 08 F1 83 11 E0 00 00 00 01 68 E9 AB 2C 8B
00 00 01 65 88 84 00 42 BF 08 EE 00 02 B2 75 8D
9F C4 24 E5 BD 27 87 F1 E4 09 A0 51 2D 12 FC F5
6E 31 3D C4 0E 3F 51 47 07 BD D2 8C AB 72 1C 2D
D0 FA 2F 7D EF AA FB 17 C1 08 AD 36 8D F1 41 35
E0 20 AE E8 75 66 39 15 78 88 01 E8 2E 4E 8A 8B
F8 04 68 BF EC 82 59 86 DE E1 66 32 37 FA 78 6D
01 EF C0 2C 6B A6 E9 36 44 4B C8 37
Adaptation fields
Adaptation_field_length: 7
discontinuity_indicator: False
random_access_indicator: True
ES_priority_indicator: False
PCR_flag: True
OPCR_flag: False
splicing_point_flag: False
transport_private_data_flag: False
adaptation_field_extension_flag: False
PCR: 50699466000
PES header
stream_id: E0 (video stream 224)
PES_packet_length: 0 (undefined)
PES_scrambling: 0
PES_priority: False
data_alignment: False
copyright: False
original_or_copy: False
PTS_flag: True
DTS_flag: True
ESCR_flag: False
ES_rate_flag: False
DSM_trick_mode_flag: False
additional_copy_info_flag: False
PES_CRC_flag: False
PES_extension_flag: False
PES_header_data_length: 10
PTS: 169128000
DTS: 169124220
Video sequence
Sequence header code not found in this packet
AFD not found in this packet
\ No newline at end of file
第3030个包解析有点问题,设置条件断点:
condition 1 ctx->ts_packet_count == 3030
发现数据如下:
(gdb) x /188xb 0x7fffffffe2f0
0x7fffffffe2f0: 0x47 0x41 0x00 0x38 0x07 0x50 0x05 0x09
0x7fffffffe2f8: 0x5a 0xa6 0x7e 0x00 0x00 0x00 0x01 0xe0
0x7fffffffe300: 0x00 0x00 0x80 0xc0 0x0a 0x31 0x28 0x53
0x7fffffffe308: 0x60 0x81 0x11 0x28 0x53 0x42 0xf9 0x00
0x7fffffffe310: 0x00 0x00 0x01 0x09 0xf0 0x00 0x00 0x00
0x7fffffffe318: 0x01 0x67 0x64 0x00 0x28 0xac 0xd1 0xc0
0x7fffffffe320: 0x50 0x05 0xbb 0xff 0x00 0x2d 0x00 0x22
0x7fffffffe328: 0x10 0x00 0x00 0x03 0x00 0x10 0x00 0x00
0x7fffffffe330: 0x03 0x03 0x08 0xf1 0x83 0x11 0xe0 0x00
0x7fffffffe338: 0x00 0x00 0x01 0x68 0xe9 0xab 0x2c 0x8b
0x7fffffffe340: 0x00 0x00 0x01 0x65 0x88 0x84 0x00 0x42
0x7fffffffe348: 0xbf 0x08 0xee 0x00 0x02 0xb2 0x75 0x8d
0x7fffffffe350: 0x9f 0xc4 0x24 0xe5 0xbd 0x27 0x87 0xf1
0x7fffffffe358: 0xe4 0x09 0xa0 0x51 0x2d 0x12 0xfc 0xf5
0x7fffffffe360: 0x6e 0x31 0x3d 0xc4 0x0e 0x3f 0x51 0x47
0x7fffffffe368: 0x07 0xbd 0xd2 0x8c 0xab 0x72 0x1c 0x2d
0x7fffffffe370: 0xd0 0xfa 0x2f 0x7d 0xef 0xaa 0xfb 0x17
0x7fffffffe378: 0xc1 0x08 0xad 0x36 0x8d 0xf1 0x41 0x35
0x7fffffffe380: 0xe0 0x20 0xae 0xe8 0x75 0x66 0x39 0x15
0x7fffffffe388: 0x78 0x88 0x01 0xe8 0x2e 0x4e 0x8a 0x8b
0x7fffffffe390: 0xf8 0x04 0x68 0xbf 0xec 0x82 0x59 0x86
0x7fffffffe398: 0xde 0xe1 0x66 0x32 0x37 0xfa 0x78 0x6d
0x7fffffffe3a0: 0x01 0xef 0xc0 0x2c 0x6b 0xa6 0xe9 0x36
0x7fffffffe3a8: 0x44 0x4b 0xc8 0x37
header解析如下:
(gdb) p *this
$74 = {_vptr.TSHeader = 0x4080b0, sync_byte = 71 'G', transport_error_indicator = 0 '\000',
payload_unit_start_indicator = 1 '\001', transport_priority = 0 '\000', pid = 256,
transport_scrambling_control = 0 '\000', adaption_field_control = TSAdaptionTypeBoth, continuity_counter = 8 '\b'}
(gdb) p ctx->get(pid)[0]
$76 = {type = TSPidTypeVideo, stream_type = TSStreamTypeVideoH264, pid = 256, continuity_counter = 8 '\b'}
(gdb) p ctx->get_msg(256)[0]
$124 = {_vptr.TSMessage = 0x408290, pid = 256, type = TSPidTypeVideo, stream_type = TSStreamTypeVideoH264,
continuity_counter = 8 '\b', PES_packet_length = 0, stream_id = 224 '\340', packet_start_code_prefix = 1,
packet_header_size = 13, parsed_packet_size = 144, packet_data_size = 144, packet_data = 0x60b300 ""}
特殊的是:PES_packet_length为0,也就是未知长度。
解析下一个包,header为:
(gdb) p header[0]
$123 = {_vptr.TSHeader = 0x408170, sync_byte = 71 'G', transport_error_indicator = 0 '\000',
payload_unit_start_indicator = 0 '\000', transport_priority = 0 '\000', pid = 256,
transport_scrambling_control = 0 '\000', adaption_field_control = TSAdaptionTypePayloadOnly,
continuity_counter = 9 '\t'}
这个包的标识是continuity_counter为上一个包的连续。这个包里面是纯粹的数据:
(gdb) x /184xb 0x7fffffffe2f4
0x7fffffffe2f4: 0x9c 0xfa 0x8c 0xc9 0x02 0x36 0xc2 0x46
0x7fffffffe2fc: 0x97 0x01 0x31 0x3d 0xfa 0x83 0xc2 0x88
0x7fffffffe304: 0x6b 0xb3 0x1c 0x63 0xcf 0xc6 0xc4 0xa6
0x7fffffffe30c: 0xe2 0xa7 0xb3 0x26 0x62 0x7e 0xb4 0xf0
0x7fffffffe314: 0x17 0x13 0x4c 0xd5 0x1b 0xee 0x80 0x37
0x7fffffffe31c: 0x8f 0x6a 0xad 0x41 0x8f 0x43 0x39 0xbe
0x7fffffffe324: 0x2f 0x51 0xb4 0x0a 0x54 0x62 0xab 0xdc
0x7fffffffe32c: 0x11 0x92 0x92 0x85 0x18 0x92 0x29 0xd5
0x7fffffffe334: 0xb5 0xbc 0x00 0x9e 0x26 0xc3 0xa4 0x04
0x7fffffffe33c: 0xb6 0x97 0x62 0x9b 0x3b 0x3c 0x09 0x6b
0x7fffffffe344: 0x68 0x15 0xe7 0xcc 0x71 0xd9 0xb5 0x02
0x7fffffffe34c: 0x19 0x8a 0x06 0x90 0x22 0xcd 0x3e 0x82
0x7fffffffe354: 0xff 0x48 0x73 0x8b 0x00 0xdc 0xe5 0xdb
0x7fffffffe35c: 0x83 0x13 0x5e 0xe8 0x63 0xe9 0xb6 0xf0
0x7fffffffe364: 0xc5 0x21 0x03 0x57 0xfb 0xb2 0xe1 0x9c
0x7fffffffe36c: 0x71 0x3e 0x36 0xe3 0x05 0xb7 0xf1 0x85
0x7fffffffe374: 0x88 0x0e 0x51 0x52 0xd8 0x3c 0x80 0x1a
0x7fffffffe37c: 0x34 0xff 0xd9 0x5f 0x69 0xb4 0x9d 0xd7
0x7fffffffe384: 0xc2 0x21 0xa8 0x85 0xc8 0xa2 0xdd 0xb8
0x7fffffffe38c: 0xa3 0x43 0x2f 0x7e 0xc8 0xac 0x1b 0x67
0x7fffffffe394: 0x17 0x6c 0x74 0xea 0x97 0xb8 0xa4 0xcf
0x7fffffffe39c: 0x43 0xf3 0x1c 0xad 0x89 0x91 0x28 0x49
0x7fffffffe3a4: 0xf2 0xe8 0x0c 0xbf 0x75 0x8a 0x1c 0xac
后续还有几个包:
$136 = {_vptr.TSHeader = 0x408250, sync_byte = 71 'G', transport_error_indicator = 0 '\000',
payload_unit_start_indicator = 0 '\000', transport_priority = 0 '\000', pid = 256,
transport_scrambling_control = 0 '\000', adaption_field_control = TSAdaptionTypePayloadOnly,
continuity_counter = 10 '\n'}
$137 = {_vptr.TSHeader = 0x408250, sync_byte = 71 'G', transport_error_indicator = 0 '\000',
payload_unit_start_indicator = 0 '\000', transport_priority = 0 '\000', pid = 256,
transport_scrambling_control = 0 '\000', adaption_field_control = TSAdaptionTypePayloadOnly,
continuity_counter = 11 '\v'}
$138 = {_vptr.TSHeader = 0x408250, sync_byte = 71 'G', transport_error_indicator = 0 '\000',
payload_unit_start_indicator = 0 '\000', transport_priority = 0 '\000', pid = 256,
transport_scrambling_control = 0 '\000', adaption_field_control = TSAdaptionTypePayloadOnly,
continuity_counter = 12 '\f'}
$141 = {_vptr.TSHeader = 0x408250, sync_byte = 71 'G', transport_error_indicator = 0 '\000',
payload_unit_start_indicator = 0 '\000', transport_priority = 0 '\000', pid = 256,
transport_scrambling_control = 0 '\000', adaption_field_control = TSAdaptionTypePayloadOnly,
continuity_counter = 13 '\r'}
$142 = {_vptr.TSHeader = 0x408250, sync_byte = 71 'G', transport_error_indicator = 0 '\000',
payload_unit_start_indicator = 0 '\000', transport_priority = 0 '\000', pid = 256,
transport_scrambling_control = 0 '\000', adaption_field_control = TSAdaptionTypePayloadOnly,
continuity_counter = 14 '\016'}
$143 = {_vptr.TSHeader = 0x408250, sync_byte = 71 'G', transport_error_indicator = 0 '\000',
payload_unit_start_indicator = 0 '\000', transport_priority = 0 '\000', pid = 256,
transport_scrambling_control = 0 '\000', adaption_field_control = TSAdaptionTypePayloadOnly,
continuity_counter = 15 '\017'}
然后,这个包变了,但是还是继续前面的包,因为是0xF溢出:
$144 = {_vptr.TSHeader = 0x408250, sync_byte = 71 'G', transport_error_indicator = 0 '\000',
payload_unit_start_indicator = 0 '\000', transport_priority = 0 '\000', pid = 256,
transport_scrambling_control = 0 '\000', adaption_field_control = TSAdaptionTypePayloadOnly,
continuity_counter = 0 '\000'}
$148 = {_vptr.TSHeader = 0x408250, sync_byte = 71 'G', transport_error_indicator = 0 '\000',
payload_unit_start_indicator = 0 '\000', transport_priority = 0 '\000', pid = 256,
transport_scrambling_control = 0 '\000', adaption_field_control = TSAdaptionTypePayloadOnly,
continuity_counter = 1 '\001'}
如此循环,可以循环很多次。一直到这个包:
$556 = {_vptr.TSHeader = 0x408250, sync_byte = 71 'G', transport_error_indicator = 0 '\000',
payload_unit_start_indicator = 1 '\001', transport_priority = 0 '\000', pid = 256,
transport_scrambling_control = 0 '\000', adaption_field_control = TSAdaptionTypePayloadOnly,
continuity_counter = 4 '\004'}
其中的:payload_unit_start_indicator为1。
\ No newline at end of file
...
...
trunk/research/ts_info.cpp
查看文件 @
a0ecc5a
...
...
@@ -13,6 +13,7 @@ g++ -o ts_info ts_info.cpp -g -O0 -ansi
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
...
...
@@ -55,22 +56,33 @@ Annex A C CRC Decoder Model
// Transport Stream packets are 188 bytes in length.
#define TS_PACKET_SIZE 188
// Program Association Table(see Table 2-25).
#define PID_PAT 0x00
// Conditional Access Table (see Table 2-27).
#define PID_CAT 0x01
// Transport Stream Description Table
#define PID_TSDT 0x02
// null packets (see Table 2-3)
#define PID_NULL 0x01FFF
enum
TSPidTable
{
// Program Association Table(see Table 2-25).
TSPidTablePAT
=
0x00
,
// Conditional Access Table (see Table 2-27).
TSPidTableCAT
=
0x01
,
// Transport Stream Description Table
TSPidTableTSDT
=
0x02
,
// null packets (see Table 2-3)
TSPidTableNULL
=
0x01FFF
,
};
/*adaptation_field_control*/
// No adaptation_field, payload only
#define AFC_PAYLOAD_ONLY 0x01
// Adaptation_field only, no payload
#define AFC_ADAPTION_ONLY 0x02
// Adaptation_field followed by payload
#define AFC_BOTH 0x03
/**
* Table 2-5 – Adaptation field control values, page 38.
*/
enum
TSAdaptionType
{
// Reserved for future use by ISO/IEC
TSAdaptionTypeReserved
=
0x00
,
// No adaptation_field, payload only
TSAdaptionTypePayloadOnly
=
0x01
,
// Adaptation_field only, no payload
TSAdaptionTypeAdaptionOnly
=
0x02
,
// Adaptation_field followed by payload
TSAdaptionTypeBoth
=
0x03
,
};
#endif
// Table 2-29 – Stream type assignments. page 66.
...
...
@@ -143,10 +155,10 @@ public:
int8_t
transport_error_indicator
;
//1bit
int8_t
payload_unit_start_indicator
;
//1bit
int8_t
transport_priority
;
//1bit
u_int16_t
pid
;
//13bits
TSPidTable
pid
;
//13bits
// 1B
int8_t
transport_scrambling_control
;
//2bits
int8_t
adaption_field_control
;
//2bits
TSAdaptionType
adaption_field_control
;
//2bits
u_int8_t
continuity_counter
;
//4bits
TSHeader
();
...
...
@@ -214,8 +226,8 @@ public:
// left bytes.
char
*
af_reserved
;
// user defined data size.
int
__user_size
;
// user defined total adaption field size.
int
__field_size
;
TSAdaptionField
();
virtual
~
TSAdaptionField
();
...
...
@@ -510,9 +522,13 @@ public:
*/
struct
TSPid
{
TSStreamType
stream_type
;
TSPidType
type
;
int16_t
pid
;
// page 66.
TSStreamType
stream_type
;
// page 36
TSPidTable
pid
;
// page 36
u_int8_t
continuity_counter
;
};
/**
...
...
@@ -523,12 +539,14 @@ class TSMessage
public
:
// 2.4.3.2 Transport Stream packet layer. page 36
// the pid of PES packet.
int16_t
pid
;
TSPidTable
pid
;
// the type of pid.
TSPidType
type
;
// the type of stream, codec type.
TSStreamType
stream_type
;
// page 36
u_int8_t
continuity_counter
;
// 2.4.3.7 Semantic definition of fields in PES packet. page 49
// PES packet header size plus data size.
...
...
@@ -569,15 +587,15 @@ public:
int
pid_size
;
TSPid
*
pids
;
int64_t
ts_packet_count
;
std
::
map
<
int16_t
,
TSMessage
*>
msgs
;
std
::
map
<
TSPidTable
,
TSMessage
*>
msgs
;
TSContext
();
virtual
~
TSContext
();
bool
exists
(
int16_t
pid
);
TSPid
*
get
(
int16_t
pid
);
void
push
(
TSStreamType
stream_type
,
TSPidType
type
,
int16_t
pid
);
bool
exists
(
TSPidTable
pid
);
TSPid
*
get
(
TSPidTable
pid
);
void
push
(
TSPidTable
pid
,
TSStreamType
stream_type
,
TSPidType
type
,
u_int8_t
continuity_counter
);
TSMessage
*
get_msg
(
int16_t
pid
);
TSMessage
*
get_msg
(
TSPidTable
pid
);
void
detach
(
TSMessage
*
msg
);
};
...
...
@@ -592,7 +610,7 @@ TSContext::~TSContext()
{
srs_freepa
(
pids
);
std
::
map
<
int16_t
,
TSMessage
*>::
iterator
it
;
std
::
map
<
TSPidTable
,
TSMessage
*>::
iterator
it
;
for
(
it
=
msgs
.
begin
();
it
!=
msgs
.
end
();
++
it
)
{
TSMessage
*
msg
=
it
->
second
;
srs_freep
(
msg
);
...
...
@@ -600,7 +618,7 @@ TSContext::~TSContext()
msgs
.
clear
();
}
bool
TSContext
::
exists
(
int16_t
pid
)
bool
TSContext
::
exists
(
TSPidTable
pid
)
{
for
(
int
i
=
0
;
i
<
pid_size
;
i
++
)
{
if
(
pid
==
pids
[
i
].
pid
)
{
...
...
@@ -611,7 +629,7 @@ bool TSContext::exists(int16_t pid)
return
false
;
}
TSPid
*
TSContext
::
get
(
int16_t
pid
)
TSPid
*
TSContext
::
get
(
TSPidTable
pid
)
{
for
(
int
i
=
0
;
i
<
pid_size
;
i
++
)
{
if
(
pid
==
pids
[
i
].
pid
)
{
...
...
@@ -622,23 +640,25 @@ TSPid* TSContext::get(int16_t pid)
return
NULL
;
}
void
TSContext
::
push
(
TS
StreamType
stream_type
,
TSPidType
type
,
int16_t
pid
)
void
TSContext
::
push
(
TS
PidTable
pid
,
TSStreamType
stream_type
,
TSPidType
type
,
u_int8_t
continuity_counter
)
{
if
(
exists
(
pid
))
{
return
;
TSPid
*
p
=
get
(
pid
);
if
(
!
p
)
{
p
=
new
TSPid
[
pid_size
+
1
];
memcpy
(
p
,
pids
,
sizeof
(
TSPid
)
*
pid_size
);
p
[
pid_size
]
=
(
TSPid
){
type
,
stream_type
,
pid
,
continuity_counter
};
pid_size
++
;
srs_freepa
(
pids
);
pids
=
p
;
}
TSPid
*
p
=
new
TSPid
[
pid_size
+
1
];
memcpy
(
p
,
pids
,
sizeof
(
TSPid
)
*
pid_size
);
p
[
pid_size
]
=
(
TSPid
){
stream_type
,
type
,
pid
};
pid_size
++
;
srs_freepa
(
pids
);
pids
=
p
;
p
->
continuity_counter
=
continuity_counter
;
}
TSMessage
*
TSContext
::
get_msg
(
int16_t
pid
)
TSMessage
*
TSContext
::
get_msg
(
TSPidTable
pid
)
{
if
(
msgs
[
pid
]
==
NULL
)
{
TSMessage
*
msg
=
new
TSMessage
();
...
...
@@ -656,7 +676,7 @@ void TSContext::detach(TSMessage* msg)
TSMessage
::
TSMessage
()
{
pid
=
0
;
pid
=
TSPidTablePAT
;
type
=
TSPidTypeReserved
;
stream_type
=
TSStreamTypeReserved
;
stream_id
=
0
;
...
...
@@ -675,11 +695,21 @@ TSMessage::~TSMessage()
void
TSMessage
::
append
(
u_int8_t
*&
p
,
int
size
)
{
if
(
size
>
0
)
{
memcpy
(
packet_data
+
parsed_packet_size
,
p
,
size
);
p
+=
size
;
parsed_packet_size
+=
size
;
if
(
size
<=
0
)
{
return
;
}
// for PES_packet_length is 0, the size is varient.
if
(
packet_data_size
-
parsed_packet_size
<
size
)
{
int
realloc_size
=
size
-
(
packet_data_size
-
parsed_packet_size
);
packet_data
=
(
char
*
)
realloc
(
packet_data
,
packet_data_size
+
realloc_size
);
packet_data_size
+=
realloc_size
;
}
memcpy
(
packet_data
+
parsed_packet_size
,
p
,
size
);
p
+=
size
;
parsed_packet_size
+=
size
;
}
void
TSMessage
::
detach
(
TSContext
*
ctx
,
TSMessage
*&
pmsg
)
...
...
@@ -729,7 +759,7 @@ TSAdaptionField::TSAdaptionField()
marker_bit2
=
0
;
af_ext_reserved
=
NULL
;
af_reserved
=
NULL
;
__
user
_size
=
0
;
__
field
_size
=
0
;
}
TSAdaptionField
::~
TSAdaptionField
()
...
...
@@ -741,7 +771,7 @@ TSAdaptionField::~TSAdaptionField()
int
TSAdaptionField
::
get_size
()
{
return
__
user
_size
;
return
__
field
_size
;
}
int
TSAdaptionField
::
demux
(
TSContext
*
ctx
,
TSPacket
*
pkt
,
u_int8_t
*
start
,
u_int8_t
*
last
,
u_int8_t
*&
p
,
TSMessage
*&
pmsg
)
...
...
@@ -750,7 +780,7 @@ int TSAdaptionField::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int
adaption_field_length
=
*
p
++
;
u_int8_t
*
pos_af
=
p
;
__
user
_size
=
1
+
adaption_field_length
;
__
field
_size
=
1
+
adaption_field_length
;
if
(
adaption_field_length
<=
0
)
{
trace
(
"ts+af empty af decoded."
);
...
...
@@ -965,7 +995,7 @@ int TSPayloadPAT::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t
pp
[
0
]
=
*
p
++
;
int16_t
pid
=
programs
[
i
]
&
0x1FFF
;
ctx
->
push
(
TSStreamTypeReserved
,
TSPidTypePMT
,
pid
);
ctx
->
push
(
(
TSPidTable
)
pid
,
TSStreamTypeReserved
,
TSPidTypePMT
,
pkt
->
header
->
continuity_counter
);
}
}
...
...
@@ -1102,12 +1132,12 @@ int TSPayloadPMT::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t
if
(
info
->
stream_type
==
TSStreamTypeVideoH264
)
{
// TODO: support more video type.
ctx
->
push
((
TS
StreamType
)
info
->
stream_type
,
TSPidTypeVideo
,
info
->
elementary_PID
);
ctx
->
push
((
TS
PidTable
)
info
->
elementary_PID
,
(
TSStreamType
)
info
->
stream_type
,
TSPidTypeVideo
,
pkt
->
header
->
continuity_counter
);
trace
(
"ts+pmt add pid: %d, type: H264 video"
,
info
->
elementary_PID
);
}
else
if
(
info
->
stream_type
==
TSStreamTypeAudioAAC
)
{
// TODO: support more audio type.
// see aac: 6.2 Audio Data Transport Stream, ADTS
ctx
->
push
((
TS
StreamType
)
info
->
stream_type
,
TSPidTypeAudio
,
info
->
elementary_PID
);
ctx
->
push
((
TS
PidTable
)
info
->
elementary_PID
,
(
TSStreamType
)
info
->
stream_type
,
TSPidTypeAudio
,
pkt
->
header
->
continuity_counter
);
trace
(
"ts+pmt add pid: %d, type: AAC audio"
,
info
->
elementary_PID
);
}
else
{
trace
(
"ts+pmt ignore the stream type: %d"
,
info
->
stream_type
);
...
...
@@ -1215,23 +1245,16 @@ int TSPayloadPES::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t
{
int
ret
=
0
;
if
(
!
pkt
->
header
->
payload_unit_start_indicator
)
{
TSMessage
*
msg
=
ctx
->
get_msg
(
pkt
->
header
->
pid
);
if
(
msg
->
packet_start_code_prefix
!=
0x01
)
{
trace
(
"ts+pes decode continous packet error, msg is empty."
);
return
-
1
;
}
msg
->
append
(
p
,
last
-
p
);
msg
->
detach
(
ctx
,
pmsg
);
return
ret
;
}
char
*
pp
=
(
char
*
)
&
packet_start_code_prefix
;
pp
[
2
]
=
*
p
++
;
pp
[
1
]
=
*
p
++
;
pp
[
0
]
=
*
p
++
;
packet_start_code_prefix
&=
0xFFFFFF
;
if
(
packet_start_code_prefix
!=
0x01
)
{
trace
(
"ts+pes decode unit start packet error, msg is empty."
);
return
-
1
;
}
stream_id
=
*
p
++
;
...
...
@@ -1413,6 +1436,7 @@ int TSPayloadPES::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t
msg
->
type
=
pid
->
type
;
msg
->
stream_type
=
pid
->
stream_type
;
msg
->
continuity_counter
=
pid
->
continuity_counter
;
msg
->
stream_id
=
stream_id
;
msg
->
packet_start_code_prefix
=
packet_start_code_prefix
;
...
...
@@ -1426,6 +1450,9 @@ int TSPayloadPES::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t
msg
->
PES_packet_length
=
PES_packet_length
;
msg
->
packet_header_size
=
p
-
pos_packet
;
msg
->
packet_data_size
=
PES_packet_length
-
msg
->
packet_header_size
;
if
(
PES_packet_length
==
0
)
{
msg
->
packet_data_size
=
last
-
p
-
msg
->
packet_header_size
;
}
if
(
msg
->
packet_data_size
>
0
)
{
msg
->
packet_data
=
new
char
[
msg
->
packet_data_size
];
...
...
@@ -1433,12 +1460,16 @@ int TSPayloadPES::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t
// PES_packet_data_byte
int
size
=
srs_min
(
msg
->
packet_data_size
,
last
-
p
);
msg
->
append
(
p
,
size
);
if
(
size
>
0
)
{
msg
->
append
(
p
,
size
);
}
msg
->
detach
(
ctx
,
pmsg
);
if
(
PES_packet_length
>
0
)
{
msg
->
detach
(
ctx
,
pmsg
);
}
trace
(
"ts+pes stream_id: %d size: %d pts: %"
PRId64
" dts: %"
PRId64
" packet_size: %d parsed_size: %d"
,
stream_id
,
PES_packet_length
,
pts
,
dts
,
msg
->
packet_data_size
,
msg
->
parsed_packet_size
);
trace
(
"ts+pes stream_id: %d size: %d pts: %"
PRId64
" dts: %"
PRId64
" total: %d header: %d packet_size: %d parsed_size: %d"
,
stream_id
,
PES_packet_length
,
pts
,
dts
,
msg
->
PES_packet_length
,
msg
->
packet_header_size
,
msg
->
packet_data_size
,
msg
->
parsed_packet_size
);
}
else
if
(
stream_id
==
PES_program_stream_map
||
stream_id
==
PES_private_stream_2
||
stream_id
==
PES_ECM_stream
...
...
@@ -1496,7 +1527,7 @@ int TSPayload::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* l
{
int
ret
=
0
;
if
(
pkt
->
header
->
pid
==
PID_
PAT
)
{
if
(
pkt
->
header
->
pid
==
TSPidTable
PAT
)
{
read_pointer_field
(
pkt
,
p
);
type
=
TSPidTypePAT
;
...
...
@@ -1550,7 +1581,7 @@ int TSPacket::demux(TSContext* ctx, u_int8_t* start, u_int8_t* last, u_int8_t*&
return
ret
;
}
if
(
header
->
adaption_field_control
==
AFC_ADAPTION_ONLY
||
header
->
adaption_field_control
==
AFC_BOTH
)
{
if
(
header
->
adaption_field_control
==
TSAdaptionTypeAdaptionOnly
||
header
->
adaption_field_control
==
TSAdaptionTypeBoth
)
{
if
((
ret
=
adaption_field
->
demux
(
ctx
,
this
,
start
,
last
,
p
,
pmsg
))
!=
0
)
{
trace
(
"ts+header af(adaption field) decode error. ret=%d"
,
ret
);
return
ret
;
...
...
@@ -1561,7 +1592,36 @@ int TSPacket::demux(TSContext* ctx, u_int8_t* start, u_int8_t* last, u_int8_t*&
// calc the user defined data size for payload.
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
(
header
->
adaption_field_control
==
TSAdaptionTypePayloadOnly
||
header
->
adaption_field_control
==
TSAdaptionTypeBoth
)
{
TSMessage
*
msg
=
ctx
->
get_msg
(
header
->
pid
);
// flush previous PES_packet_length(0) packets.
if
(
msg
->
packet_start_code_prefix
==
0x01
&&
header
->
payload_unit_start_indicator
==
1
&&
msg
->
PES_packet_length
==
0
)
{
msg
->
detach
(
ctx
,
pmsg
);
// reparse current message
p
=
start
;
return
ret
;
}
// parse continous packet.
if
(
!
header
->
payload_unit_start_indicator
)
{
if
(
msg
->
packet_start_code_prefix
!=
0x01
)
{
trace
(
"ts+pes decode continous packet error, msg is empty."
);
return
-
1
;
}
msg
->
append
(
p
,
last
-
p
);
// for PES_packet_length is 0, donot attach it.
if
(
msg
->
PES_packet_length
>
0
)
{
msg
->
detach
(
ctx
,
pmsg
);
}
return
ret
;
}
// parse new packet.
if
((
ret
=
payload
->
demux
(
ctx
,
this
,
start
,
last
,
p
,
pmsg
))
!=
0
)
{
trace
(
"ts+header payload decode error. ret=%d"
,
ret
);
return
ret
;
...
...
@@ -1588,9 +1648,9 @@ TSHeader::TSHeader()
transport_error_indicator
=
0
;
payload_unit_start_indicator
=
0
;
transport_priority
=
0
;
pid
=
0
;
pid
=
TSPidTablePAT
;
transport_scrambling_control
=
0
;
adaption_field_control
=
0
;
adaption_field_control
=
TSAdaptionTypeReserved
;
continuity_counter
=
0
;
}
...
...
@@ -1614,23 +1674,27 @@ int TSHeader::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* la
return
-
1
;
}
pid
=
0
;
((
char
*
)
&
pid
)[
1
]
=
*
p
++
;
((
char
*
)
&
pid
)[
0
]
=
*
p
++
;
int16_t
_pid
=
0
;
char
*
pp
=
(
char
*
)
&
_pid
;
pp
[
1
]
=
*
p
++
;
pp
[
0
]
=
*
p
++
;
transport_error_indicator
=
(
pid
>>
15
)
&
0x01
;
payload_unit_start_indicator
=
(
pid
>>
14
)
&
0x01
;
transport_priority
=
(
pid
>>
13
)
&
0x01
;
pid
&=
0x1FFF
;
transport_error_indicator
=
(
_pid
>>
15
)
&
0x01
;
payload_unit_start_indicator
=
(
_pid
>>
14
)
&
0x01
;
transport_priority
=
(
_pid
>>
13
)
&
0x01
;
_pid
&=
0x1FFF
;
ctx
->
push
(
TSStreamTypeReserved
,
TSPidTypePAT
,
pid
)
;
pid
=
(
TSPidTable
)
_pid
;
continuity_counter
=
*
p
++
;
transport_scrambling_control
=
(
continuity_counter
>>
6
)
&
0x03
;
adaption_field_control
=
(
continuity_counter
>>
4
)
&
0x03
;
int8_t
_adaption_field_control
=
(
continuity_counter
>>
4
)
&
0x03
;
adaption_field_control
=
(
TSAdaptionType
)
_adaption_field_control
;
continuity_counter
&=
0x0F
;
ctx
->
push
(
pid
,
TSStreamTypeReserved
,
TSPidTypePAT
,
continuity_counter
);
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
);
...
...
@@ -1934,24 +1998,27 @@ int main(int /*argc*/, char** /*argv*/)
u_int8_t
*
start
=
ts_packet
;
u_int8_t
*
last
=
ts_packet
+
TS_PACKET_SIZE
;
TSPacket
pkt
;
TSMessage
*
msg
=
NULL
;
if
((
ret
=
pkt
.
demux
(
&
ctx
,
start
,
last
,
p
,
msg
))
!=
0
)
{
trace
(
"demuxer+read decode ts packet error. ret=%d"
,
ret
);
return
ret
;
}
offset
+=
nread
;
if
(
!
msg
)
{
continue
;
}
if
((
ret
=
consume
(
msg
))
!=
0
)
{
trace
(
"demuxer+consume parse and consume message failed. ret=%d"
,
ret
);
break
;
// maybe need to parse multiple times for the PES_packet_length(0) packets.
while
(
p
==
start
)
{
TSPacket
pkt
;
TSMessage
*
msg
=
NULL
;
if
((
ret
=
pkt
.
demux
(
&
ctx
,
start
,
last
,
p
,
msg
))
!=
0
)
{
trace
(
"demuxer+read decode ts packet error. ret=%d"
,
ret
);
return
ret
;
}
offset
+=
nread
;
if
(
!
msg
)
{
continue
;
}
if
((
ret
=
consume
(
msg
))
!=
0
)
{
trace
(
"demuxer+consume parse and consume message failed. ret=%d"
,
ret
);
break
;
}
srs_freep
(
msg
);
}
srs_freep
(
msg
);
}
close
(
fd
);
...
...
请
注册
或
登录
后发表评论