Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-1.1
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc-1.1
Commits
66f1e9dd
Commit
66f1e9dd
authored
Sep 25, 2005
by
Jean-Paul Saman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix several memory leaks and do a bit of coding style cleanup.
parent
3143ebce
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
946 additions
and
879 deletions
+946
-879
modules/access/rtsp/real.c
modules/access/rtsp/real.c
+338
-302
modules/access/rtsp/real_rmff.c
modules/access/rtsp/real_rmff.c
+336
-321
modules/access/rtsp/real_rmff.h
modules/access/rtsp/real_rmff.h
+3
-4
modules/access/rtsp/real_sdpplin.c
modules/access/rtsp/real_sdpplin.c
+263
-246
modules/access/rtsp/rtsp.c
modules/access/rtsp/rtsp.c
+6
-6
No files found.
modules/access/rtsp/real.c
View file @
66f1e9dd
...
...
@@ -47,17 +47,16 @@ const unsigned char xor_table[] = {
#define MAX(x,y) ((x>y) ? x : y)
static
void
hash
(
char
*
field
,
char
*
param
)
{
static
void
hash
(
char
*
field
,
char
*
param
)
{
uint32_t
a
,
b
,
c
,
d
;
/* fill variables */
a
=
LE_32
(
field
);
b
=
LE_32
(
field
+
4
);
c
=
LE_32
(
field
+
8
);
d
=
LE_32
(
field
+
12
);
lprintf
(
"hash input: %x %x %x %x
\n
"
,
a
,
b
,
c
,
d
);
lprintf
(
"hash parameter:
\n
"
);
...
...
@@ -126,7 +125,7 @@ static void hash(char *field, char *param) {
c
=
((
c
<<
0x0e
)
|
(
c
>>
0x12
))
+
d
;
b
=
((
c
&
a
)
|
(
~
a
&
d
))
+
LE_32
((
param
+
0x30
))
+
b
-
0x72D5B376
;
b
=
((
b
<<
0x14
)
|
(
b
>>
0x0c
))
+
c
;
a
=
(
b
^
c
^
d
)
+
LE_32
((
param
+
0x14
))
+
a
-
0x0005C6BE
;
a
=
((
a
<<
0x04
)
|
(
a
>>
0x1c
))
+
b
;
d
=
(
a
^
b
^
c
)
+
LE_32
((
param
+
0x20
))
+
d
-
0x788E097F
;
...
...
@@ -159,7 +158,7 @@ static void hash(char *field, char *param) {
c
=
((
c
<<
0x10
)
|
(
c
>>
0x10
))
+
d
;
b
=
(
c
^
d
^
a
)
+
LE_32
((
param
+
0x08
))
+
b
-
0x3B53A99B
;
b
=
((
b
<<
0x17
)
|
(
b
>>
0x09
))
+
c
;
a
=
((
~
d
|
b
)
^
c
)
+
LE_32
((
param
+
0x00
))
+
a
-
0x0BD6DDBC
;
a
=
((
a
<<
0x06
)
|
(
a
>>
0x1a
))
+
b
;
d
=
((
~
c
|
a
)
^
b
)
+
LE_32
((
param
+
0x1c
))
+
d
+
0x432AFF97
;
...
...
@@ -194,7 +193,7 @@ static void hash(char *field, char *param) {
b
=
((
b
<<
0x15
)
|
(
b
>>
0x0b
))
+
c
;
lprintf
(
"hash output: %x %x %x %x
\n
"
,
a
,
b
,
c
,
d
);
a
+=
LE_32
(
field
);
b
+=
LE_32
(
field
+
4
);
c
+=
LE_32
(
field
+
8
);
...
...
@@ -210,15 +209,15 @@ static void call_hash (char *key, char *challenge, int len) {
uint8_t
*
ptr1
,
*
ptr2
;
uint32_t
a
,
b
,
c
,
d
,
tmp
;
ptr1
=
(
key
+
16
);
ptr2
=
(
key
+
20
);
a
=
LE_32
(
ptr1
);
b
=
(
a
>>
3
)
&
0x3f
;
a
+=
len
*
8
;
LE_32C
(
ptr1
,
a
);
if
(
a
<
(
len
<<
3
))
{
lprintf
(
"not verified: (len << 3) > a true
\n
"
);
...
...
@@ -228,15 +227,14 @@ static void call_hash (char *key, char *challenge, int len) {
tmp
=
LE_32
(
ptr2
)
+
(
len
>>
0x1d
);
LE_32C
(
ptr2
,
tmp
);
a
=
64
-
b
;
c
=
0
;
c
=
0
;
if
(
a
<=
len
)
{
memcpy
(
key
+
b
+
24
,
challenge
,
a
);
hash
(
key
,
key
+
24
);
c
=
a
;
d
=
c
+
0x3f
;
while
(
d
<
len
)
{
lprintf
(
"not verified: while ( d < len )
\n
"
);
hash
(
key
,
challenge
+
d
-
0x3f
);
...
...
@@ -245,44 +243,43 @@ static void call_hash (char *key, char *challenge, int len) {
}
b
=
0
;
}
memcpy
(
key
+
b
+
24
,
challenge
+
c
,
len
-
c
);
}
static
void
calc_response
(
char
*
result
,
char
*
field
)
{
static
void
calc_response
(
char
*
result
,
char
*
field
)
{
char
buf1
[
128
];
char
buf2
[
128
];
int
i
;
memset
(
buf1
,
0
,
64
);
*
buf1
=
128
;
memcpy
(
buf2
,
field
+
16
,
8
);
i
=
(
LE_32
((
buf2
))
>>
3
)
&
0x3f
;
if
(
i
<
56
)
{
if
(
i
<
56
)
{
i
=
56
-
i
;
}
else
{
}
else
{
lprintf
(
"not verified: ! (i < 56)
\n
"
);
i
=
120
-
i
;
}
call_hash
(
field
,
buf1
,
i
);
call_hash
(
field
,
buf2
,
8
);
memcpy
(
result
,
field
,
16
);
}
static
void
calc_response_string
(
char
*
result
,
char
*
challenge
)
{
static
void
calc_response_string
(
char
*
result
,
char
*
challenge
)
{
char
field
[
128
];
char
zres
[
20
];
int
i
;
/* initialize our field */
BE_32C
(
field
,
0x01234567
);
BE_32C
((
field
+
4
),
0x89ABCDEF
);
...
...
@@ -294,11 +291,11 @@ static void calc_response_string (char *result, char *challenge) {
/* calculate response */
call_hash
(
field
,
challenge
,
64
);
calc_response
(
zres
,
field
);
/* convert zres to ascii string */
for
(
i
=
0
;
i
<
16
;
i
++
)
{
char
a
,
b
;
a
=
(
zres
[
i
]
>>
4
)
&
15
;
b
=
zres
[
i
]
&
15
;
...
...
@@ -307,8 +304,8 @@ static void calc_response_string (char *result, char *challenge) {
}
}
void
real_calc_response_and_checksum
(
char
*
response
,
char
*
chksum
,
char
*
challenge
)
{
void
real_calc_response_and_checksum
(
char
*
response
,
char
*
chksum
,
char
*
challenge
)
{
int
ch_len
,
table_len
,
resp_len
;
int
i
;
char
*
ptr
;
...
...
@@ -337,11 +334,11 @@ void real_calc_response_and_checksum (char *response, char *chksum, char *challe
ch_len
=
32
;
}
if
(
ch_len
>
56
)
ch_len
=
56
;
/* copy challenge to buf */
memcpy
(
ptr
,
challenge
,
ch_len
);
}
if
(
xor_table
!=
NULL
)
{
table_len
=
strlen
(
xor_table
);
...
...
@@ -369,14 +366,12 @@ void real_calc_response_and_checksum (char *response, char *chksum, char *challe
* takes a MLTI-Chunk and a rule number got from match_asm_rule,
* returns a pointer to selected data and number of bytes in that.
*/
static
int
select_mlti_data
(
const
char
*
mlti_chunk
,
int
mlti_size
,
int
selection
,
char
**
out
)
{
static
int
select_mlti_data
(
const
char
*
mlti_chunk
,
int
mlti_size
,
int
selection
,
char
**
out
)
{
int
numrules
,
codec
,
size
;
int
i
;
/* MLTI chunk should begin with MLTI */
/* MLTI chunk should begin with MLTI */
if
((
mlti_chunk
[
0
]
!=
'M'
)
||
(
mlti_chunk
[
1
]
!=
'L'
)
||
(
mlti_chunk
[
2
]
!=
'T'
)
...
...
@@ -412,13 +407,12 @@ static int select_mlti_data(const char *mlti_chunk, int mlti_size, int selection
}
mlti_chunk
+=
2
;
/* now seek to selected codec */
for
(
i
=
0
;
i
<
codec
;
i
++
)
{
size
=
BE_32
(
mlti_chunk
);
mlti_chunk
+=
size
+
4
;
}
size
=
BE_32
(
mlti_chunk
);
memcpy
(
*
out
,
mlti_chunk
+
4
,
size
);
...
...
@@ -429,301 +423,343 @@ static int select_mlti_data(const char *mlti_chunk, int mlti_size, int selection
* looking at stream description.
*/
rmff_header_t
*
real_parse_sdp
(
char
*
data
,
char
**
stream_rules
,
uint32_t
bandwidth
)
{
sdpplin_t
*
desc
;
rmff_header_t
*
header
;
char
*
buf
;
int
len
,
i
;
int
max_bit_rate
=
0
;
int
avg_bit_rate
=
0
;
int
max_packet_size
=
0
;
int
avg_packet_size
=
0
;
int
duration
=
0
;
if
(
!
data
)
return
NULL
;
desc
=
sdpplin_parse
(
data
);
if
(
!
desc
)
return
NULL
;
buf
=
malloc
(
2048
);
header
=
malloc
(
sizeof
(
rmff_header_t
));
memset
(
header
,
0
,
sizeof
(
rmff_header_t
));
header
->
fileheader
=
rmff_new_fileheader
(
4
+
desc
->
stream_count
);
header
->
cont
=
rmff_new_cont
(
desc
->
title
,
desc
->
author
,
desc
->
copyright
,
desc
->
abstract
);
header
->
data
=
rmff_new_dataheader
(
0
,
0
);
header
->
streams
=
malloc
(
sizeof
(
rmff_mdpr_t
*
)
*
(
desc
->
stream_count
+
1
));
memset
(
header
->
streams
,
0
,
sizeof
(
rmff_mdpr_t
*
)
*
(
desc
->
stream_count
+
1
));
lprintf
(
"number of streams: %u
\n
"
,
desc
->
stream_count
);
for
(
i
=
0
;
i
<
desc
->
stream_count
;
i
++
)
{
int
j
=
0
;
int
n
;
char
b
[
64
];
int
rulematches
[
16
];
lprintf
(
"calling asmrp_match with:
\n
%s
\n
%u
\n
"
,
desc
->
stream
[
i
]
->
asm_rule_book
,
bandwidth
);
rmff_header_t
*
real_parse_sdp
(
char
*
data
,
char
**
stream_rules
,
uint32_t
bandwidth
)
{
sdpplin_t
*
desc
=
NULL
;
rmff_header_t
*
header
=
NULL
;
char
*
buf
=
NULL
;
int
len
,
i
;
int
max_bit_rate
=
0
;
int
avg_bit_rate
=
0
;
int
max_packet_size
=
0
;
int
avg_packet_size
=
0
;
int
duration
=
0
;
if
(
!
data
)
return
NULL
;
desc
=
sdpplin_parse
(
data
);
if
(
!
desc
)
return
NULL
;
buf
=
(
char
*
)
malloc
(
sizeof
(
char
)
*
2048
);
if
(
!
buf
)
goto
error
;
header
=
(
rmff_header_t
*
)
malloc
(
sizeof
(
rmff_header_t
));
if
(
!
header
)
goto
error
;
memset
(
header
,
0
,
sizeof
(
rmff_header_t
));
header
->
fileheader
=
rmff_new_fileheader
(
4
+
desc
->
stream_count
);
header
->
cont
=
rmff_new_cont
(
desc
->
title
,
desc
->
author
,
desc
->
copyright
,
desc
->
abstract
);
header
->
data
=
rmff_new_dataheader
(
0
,
0
);
if
(
!
header
->
data
)
goto
error
;
header
->
streams
=
(
rmff_mdpr_t
*
)
malloc
(
sizeof
(
rmff_mdpr_t
*
)
*
(
desc
->
stream_count
+
1
));
if
(
!
header
->
streams
)
goto
error
;
memset
(
header
->
streams
,
0
,
sizeof
(
rmff_mdpr_t
*
)
*
(
desc
->
stream_count
+
1
));
lprintf
(
"number of streams: %u
\n
"
,
desc
->
stream_count
);
for
(
i
=
0
;
i
<
desc
->
stream_count
;
i
++
)
{
int
j
=
0
;
int
n
;
char
b
[
64
];
int
rulematches
[
16
];
lprintf
(
"calling asmrp_match with:
\n
%s
\n
%u
\n
"
,
desc
->
stream
[
i
]
->
asm_rule_book
,
bandwidth
);
n
=
asmrp_match
(
desc
->
stream
[
i
]
->
asm_rule_book
,
bandwidth
,
rulematches
);
for
(
j
=
0
;
j
<
n
;
j
++
)
{
lprintf
(
"asmrp rule match: %u for stream %u
\n
"
,
rulematches
[
j
],
desc
->
stream
[
i
]
->
stream_id
);
sprintf
(
b
,
"stream=%u;rule=%u,"
,
desc
->
stream
[
i
]
->
stream_id
,
rulematches
[
j
]);
strcat
(
*
stream_rules
,
b
);
}
if
(
!
desc
->
stream
[
i
]
->
mlti_data
)
{
len
=
0
;
if
(
buf
)
free
(
buf
);
buf
=
NULL
;
}
else
len
=
select_mlti_data
(
desc
->
stream
[
i
]
->
mlti_data
,
desc
->
stream
[
i
]
->
mlti_data_size
,
rulematches
[
0
],
&
buf
);
header
->
streams
[
i
]
=
rmff_new_mdpr
(
desc
->
stream
[
i
]
->
stream_id
,
desc
->
stream
[
i
]
->
max_bit_rate
,
desc
->
stream
[
i
]
->
avg_bit_rate
,
desc
->
stream
[
i
]
->
max_packet_size
,
desc
->
stream
[
i
]
->
avg_packet_size
,
desc
->
stream
[
i
]
->
start_time
,
desc
->
stream
[
i
]
->
preroll
,
desc
->
stream
[
i
]
->
duration
,
desc
->
stream
[
i
]
->
stream_name
,
desc
->
stream
[
i
]
->
mime_type
,
len
,
buf
);
if
(
!
header
->
streams
[
i
]
)
goto
error
;
duration
=
MAX
(
duration
,
desc
->
stream
[
i
]
->
duration
);
max_bit_rate
+=
desc
->
stream
[
i
]
->
max_bit_rate
;
avg_bit_rate
+=
desc
->
stream
[
i
]
->
avg_bit_rate
;
max_packet_size
=
MAX
(
max_packet_size
,
desc
->
stream
[
i
]
->
max_packet_size
);
if
(
avg_packet_size
)
avg_packet_size
=
(
avg_packet_size
+
desc
->
stream
[
i
]
->
avg_packet_size
)
/
2
;
else
avg_packet_size
=
desc
->
stream
[
i
]
->
avg_packet_size
;
}
n
=
asmrp_match
(
desc
->
stream
[
i
]
->
asm_rule_book
,
bandwidth
,
rulematches
);
for
(
j
=
0
;
j
<
n
;
j
++
)
{
lprintf
(
"asmrp rule match: %u for stream %u
\n
"
,
rulematches
[
j
],
desc
->
stream
[
i
]
->
stream_id
);
sprintf
(
b
,
"stream=%u;rule=%u,"
,
desc
->
stream
[
i
]
->
stream_id
,
rulematches
[
j
]);
strcat
(
*
stream_rules
,
b
);
if
(
*
stream_rules
&&
strlen
(
*
stream_rules
)
&&
(
*
stream_rules
)[
strlen
(
*
stream_rules
)
-
1
]
==
','
)
(
*
stream_rules
)[
strlen
(
*
stream_rules
)
-
1
]
=
0
;
/* delete last ',' in stream_rules */
header
->
prop
=
rmff_new_prop
(
max_bit_rate
,
avg_bit_rate
,
max_packet_size
,
avg_packet_size
,
0
,
duration
,
0
,
0
,
0
,
desc
->
stream_count
,
desc
->
flags
);
if
(
!
header
->
prop
)
goto
error
;
rmff_fix_header
(
header
);
if
(
desc
)
{
sdpplin_free
(
desc
);
free
(
desc
);
}
if
(
buf
)
free
(
buf
);
return
header
;
if
(
!
desc
->
stream
[
i
]
->
mlti_data
)
{
len
=
0
;
buf
=
NULL
;
error:
if
(
desc
)
{
sdpplin_free
(
desc
);
free
(
desc
);
}
else
len
=
select_mlti_data
(
desc
->
stream
[
i
]
->
mlti_data
,
desc
->
stream
[
i
]
->
mlti_data_size
,
rulematches
[
0
],
&
buf
);
header
->
streams
[
i
]
=
rmff_new_mdpr
(
desc
->
stream
[
i
]
->
stream_id
,
desc
->
stream
[
i
]
->
max_bit_rate
,
desc
->
stream
[
i
]
->
avg_bit_rate
,
desc
->
stream
[
i
]
->
max_packet_size
,
desc
->
stream
[
i
]
->
avg_packet_size
,
desc
->
stream
[
i
]
->
start_time
,
desc
->
stream
[
i
]
->
preroll
,
desc
->
stream
[
i
]
->
duration
,
desc
->
stream
[
i
]
->
stream_name
,
desc
->
stream
[
i
]
->
mime_type
,
len
,
buf
);
duration
=
MAX
(
duration
,
desc
->
stream
[
i
]
->
duration
);
max_bit_rate
+=
desc
->
stream
[
i
]
->
max_bit_rate
;
avg_bit_rate
+=
desc
->
stream
[
i
]
->
avg_bit_rate
;
max_packet_size
=
MAX
(
max_packet_size
,
desc
->
stream
[
i
]
->
max_packet_size
);
if
(
avg_packet_size
)
avg_packet_size
=
(
avg_packet_size
+
desc
->
stream
[
i
]
->
avg_packet_size
)
/
2
;
else
avg_packet_size
=
desc
->
stream
[
i
]
->
avg_packet_size
;
}
if
(
*
stream_rules
&&
strlen
(
*
stream_rules
)
&&
(
*
stream_rules
)[
strlen
(
*
stream_rules
)
-
1
]
==
','
)
(
*
stream_rules
)[
strlen
(
*
stream_rules
)
-
1
]
=
0
;
/* delete last ',' in stream_rules */
header
->
prop
=
rmff_new_prop
(
max_bit_rate
,
avg_bit_rate
,
max_packet_size
,
avg_packet_size
,
0
,
duration
,
0
,
0
,
0
,
desc
->
stream_count
,
desc
->
flags
);
rmff_fix_header
(
header
);
free
(
buf
);
return
header
;
if
(
header
)
{
rmff_free_header
(
header
);
free
(
header
);
}
if
(
buf
)
free
(
buf
);
return
NULL
;
}
int
real_get_rdt_chunk_header
(
rtsp_client_t
*
rtsp_session
,
rmff_pheader_t
*
ph
)
{
int
n
=
1
;
uint8_t
header
[
8
];
int
size
;
int
flags1
;
int
unknown1
;
uint32_t
ts
;
n
=
rtsp_read_data
(
rtsp_session
,
header
,
8
);
if
(
n
<
8
)
return
0
;
if
(
header
[
0
]
!=
0x24
)
{
lprintf
(
"rdt chunk not recognized: got 0x%02x
\n
"
,
header
[
0
]);
return
0
;
}
size
=
(
header
[
1
]
<<
16
)
+
(
header
[
2
]
<<
8
)
+
(
header
[
3
]);
flags1
=
header
[
4
];
if
((
flags1
!=
0x40
)
&&
(
flags1
!=
0x42
))
{
lprintf
(
"got flags1: 0x%02x
\n
"
,
flags1
);
if
(
header
[
6
]
==
0x06
)
int
n
=
1
;
uint8_t
header
[
8
];
int
size
;
int
flags1
;
int
unknown1
;
uint32_t
ts
;
n
=
rtsp_read_data
(
rtsp_session
,
header
,
8
);
if
(
n
<
8
)
return
0
;
if
(
header
[
0
]
!=
0x24
)
{
lprintf
(
"got end of stream packet
\n
"
);
return
0
;
lprintf
(
"rdt chunk not recognized: got 0x%02x
\n
"
,
header
[
0
]
);
return
0
;
}
header
[
0
]
=
header
[
5
];
header
[
1
]
=
header
[
6
];
header
[
2
]
=
header
[
7
];
n
=
rtsp_read_data
(
rtsp_session
,
header
+
3
,
5
);
if
(
n
<
5
)
return
0
;
lprintf
(
"ignoring bytes:
\n
"
);
n
=
rtsp_read_data
(
rtsp_session
,
header
+
4
,
4
);
if
(
n
<
4
)
return
0
;
size
=
(
header
[
1
]
<<
16
)
+
(
header
[
2
]
<<
8
)
+
(
header
[
3
]);
flags1
=
header
[
4
];
size
-=
9
;
}
unknown1
=
(
header
[
5
]
<<
16
)
+
(
header
[
6
]
<<
8
)
+
(
header
[
7
]);
n
=
rtsp_read_data
(
rtsp_session
,
header
,
6
);
if
(
n
<
6
)
return
0
;
ts
=
BE_32
(
header
);
if
((
flags1
!=
0x40
)
&&
(
flags1
!=
0x42
))
{
lprintf
(
"got flags1: 0x%02x
\n
"
,
flags1
);
if
(
header
[
6
]
==
0x06
)
{
lprintf
(
"got end of stream packet
\n
"
);
return
0
;
}
header
[
0
]
=
header
[
5
];
header
[
1
]
=
header
[
6
];
header
[
2
]
=
header
[
7
];
n
=
rtsp_read_data
(
rtsp_session
,
header
+
3
,
5
);
if
(
n
<
5
)
return
0
;
lprintf
(
"ignoring bytes:
\n
"
);
n
=
rtsp_read_data
(
rtsp_session
,
header
+
4
,
4
);
if
(
n
<
4
)
return
0
;
flags1
=
header
[
4
];
size
-=
9
;
}
unknown1
=
(
header
[
5
]
<<
16
)
+
(
header
[
6
]
<<
8
)
+
(
header
[
7
]);
n
=
rtsp_read_data
(
rtsp_session
,
header
,
6
);
if
(
n
<
6
)
return
0
;
ts
=
BE_32
(
header
);
#if 0
lprintf("ts: %u size: %u, flags: 0x%02x, unknown values: %u 0x%02x 0x%02x\n",
ts, size, flags1, unknown1, header[4], header[5]);
lprintf("ts: %u size: %u, flags: 0x%02x, unknown values: %u 0x%02x 0x%02x\n",
ts, size, flags1, unknown1, header[4], header[5]);
#endif
size
+=
2
;
ph
->
object_version
=
0
;
ph
->
length
=
size
;
ph
->
stream_number
=
(
flags1
>>
1
)
&
1
;
ph
->
timestamp
=
ts
;
ph
->
reserved
=
0
;
ph
->
flags
=
0
;
/* TODO: determine keyframe flag and insert here? */
return
size
;
size
+=
2
;
ph
->
object_version
=
0
;
ph
->
length
=
size
;
ph
->
stream_number
=
(
flags1
>>
1
)
&
1
;
ph
->
timestamp
=
ts
;
ph
->
reserved
=
0
;
ph
->
flags
=
0
;
/* TODO: determine keyframe flag and insert here? */
return
size
;
}
int
real_get_rdt_chunk
(
rtsp_client_t
*
rtsp_session
,
rmff_pheader_t
*
ph
,
unsigned
char
**
buffer
)
{
int
n
;
rmff_dump_pheader
(
ph
,
*
buffer
);
n
=
rtsp_read_data
(
rtsp_session
,
*
buffer
+
12
,
ph
->
length
-
12
);
return
(
n
<=
0
)
?
0
:
n
+
12
;
int
n
;
rmff_dump_pheader
(
ph
,
*
buffer
);
n
=
rtsp_read_data
(
rtsp_session
,
*
buffer
+
12
,
ph
->
length
-
12
);
return
(
n
<=
0
)
?
0
:
n
+
12
;
}
//! maximum size of the rtsp description, must be < INT_MAX
#define MAX_DESC_BUF (20 * 1024 * 1024)
rmff_header_t
*
real_setup_and_get_header
(
rtsp_client_t
*
rtsp_session
,
int
bandwidth
)
{
char
*
description
=
NULL
;
char
*
session_id
=
NULL
;
rmff_header_t
*
h
;
char
*
challenge1
;
char
challenge2
[
64
];
char
checksum
[
34
];
char
*
subscribe
;
char
*
buf
=
malloc
(
256
);
char
*
mrl
=
rtsp_get_mrl
(
rtsp_session
);
unsigned
int
size
;
int
status
;
/* get challenge */
challenge1
=
strdup
(
rtsp_search_answers
(
rtsp_session
,
"RealChallenge1"
));
lprintf
(
"Challenge1: %s
\n
"
,
challenge1
);
/* request stream description */
rtsp_schedule_field
(
rtsp_session
,
"Accept: application/sdp"
);
sprintf
(
buf
,
"Bandwidth: %u"
,
bandwidth
);
rtsp_schedule_field
(
rtsp_session
,
buf
);
rtsp_schedule_field
(
rtsp_session
,
"GUID: 00000000-0000-0000-0000-000000000000"
);
rtsp_schedule_field
(
rtsp_session
,
"RegionData: 0"
);
rtsp_schedule_field
(
rtsp_session
,
"ClientID: Linux_2.4_6.0.9.1235_play32_RN01_EN_586"
);
rtsp_schedule_field
(
rtsp_session
,
"SupportsMaximumASMBandwidth: 1"
);
rtsp_schedule_field
(
rtsp_session
,
"Language: en-US"
);
rtsp_schedule_field
(
rtsp_session
,
"Require: com.real.retain-entity-for-setup"
);
status
=
rtsp_request_describe
(
rtsp_session
,
NULL
);
if
(
status
<
200
||
status
>
299
)
{
char
*
alert
=
rtsp_search_answers
(
rtsp_session
,
"Alert"
);
if
(
alert
)
{
lprintf
(
"real: got message from server:
\n
%s
\n
"
,
alert
);
rmff_header_t
*
real_setup_and_get_header
(
rtsp_client_t
*
rtsp_session
,
int
bandwidth
)
{
char
*
description
=
NULL
;
char
*
session_id
=
NULL
;
rmff_header_t
*
h
;
char
*
challenge1
=
NULL
;
char
challenge2
[
64
];
char
checksum
[
34
];
char
*
subscribe
=
NULL
;
char
*
buf
=
(
char
*
)
malloc
(
sizeof
(
char
)
*
256
);
char
*
mrl
=
rtsp_get_mrl
(
rtsp_session
);
unsigned
int
size
;
int
status
;
/* get challenge */
challenge1
=
strdup
(
rtsp_search_answers
(
rtsp_session
,
"RealChallenge1"
));
lprintf
(
"Challenge1: %s
\n
"
,
challenge1
);
/* request stream description */
rtsp_schedule_field
(
rtsp_session
,
"Accept: application/sdp"
);
sprintf
(
buf
,
"Bandwidth: %u"
,
bandwidth
);
rtsp_schedule_field
(
rtsp_session
,
buf
);
rtsp_schedule_field
(
rtsp_session
,
"GUID: 00000000-0000-0000-0000-000000000000"
);
rtsp_schedule_field
(
rtsp_session
,
"RegionData: 0"
);
rtsp_schedule_field
(
rtsp_session
,
"ClientID: Linux_2.4_6.0.9.1235_play32_RN01_EN_586"
);
rtsp_schedule_field
(
rtsp_session
,
"SupportsMaximumASMBandwidth: 1"
);
rtsp_schedule_field
(
rtsp_session
,
"Language: en-US"
);
rtsp_schedule_field
(
rtsp_session
,
"Require: com.real.retain-entity-for-setup"
);
status
=
rtsp_request_describe
(
rtsp_session
,
NULL
);
if
(
status
<
200
||
status
>
299
)
{
char
*
alert
=
rtsp_search_answers
(
rtsp_session
,
"Alert"
);
if
(
alert
)
{
lprintf
(
"real: got message from server:
\n
%s
\n
"
,
alert
);
}
printf
(
"bou
\n
"
);
rtsp_send_ok
(
rtsp_session
);
if
(
challenge1
)
free
(
challenge1
);
if
(
alert
)
free
(
alert
);
if
(
buf
)
free
(
buf
);
return
NULL
;
}
printf
(
"bou
\n
"
);
rtsp_send_ok
(
rtsp_session
);
free
(
buf
);
return
NULL
;
}
/* receive description */
size
=
0
;
if
(
!
rtsp_search_answers
(
rtsp_session
,
"Content-length"
))
lprintf
(
"real: got no Content-length!
\n
"
);
else
size
=
atoi
(
rtsp_search_answers
(
rtsp_session
,
"Content-length"
));
if
(
size
>
MAX_DESC_BUF
)
{
printf
(
"real: Content-length for description too big (> %uMB)!
\n
"
,
MAX_DESC_BUF
/
(
1024
*
1024
)
);
free
(
buf
);
return
NULL
;
}
if
(
!
rtsp_search_answers
(
rtsp_session
,
"ETag"
))
lprintf
(
"real: got no ETag!
\n
"
);
else
session_id
=
strdup
(
rtsp_search_answers
(
rtsp_session
,
"ETag"
));
lprintf
(
"Stream description size: %i
\n
"
,
size
);
description
=
malloc
(
sizeof
(
char
)
*
(
size
+
1
));
/* receive description */
size
=
0
;
if
(
!
rtsp_search_answers
(
rtsp_session
,
"Content-length"
))
lprintf
(
"real: got no Content-length!
\n
"
);
else
size
=
atoi
(
rtsp_search_answers
(
rtsp_session
,
"Content-length"
));
if
(
rtsp_read_data
(
rtsp_session
,
description
,
size
)
<=
0
)
{
free
(
buf
);
return
NULL
;
}
description
[
size
]
=
0
;
fprintf
(
stderr
,
description
);
/* parse sdp (sdpplin) and create a header and a subscribe string */
subscribe
=
malloc
(
256
);
strcpy
(
subscribe
,
"Subscribe: "
);
h
=
real_parse_sdp
(
description
,
&
subscribe
,
bandwidth
);
if
(
!
h
)
{
free
(
subscribe
);
free
(
buf
);
return
NULL
;
}
rmff_fix_header
(
h
);
if
(
size
>
MAX_DESC_BUF
)
{
printf
(
"real: Content-length for description too big (> %uMB)!
\n
"
,
MAX_DESC_BUF
/
(
1024
*
1024
)
);
goto
error
;
}
#if 0
fprintf("Title: %s\nCopyright: %s\nAuthor: %s\nStreams: %i\n",
h->cont->title, h->cont->copyright, h->cont->author, h->prop->num_streams);
#endif
/* setup our streams */
real_calc_response_and_checksum
(
challenge2
,
checksum
,
challenge1
);
buf
=
realloc
(
buf
,
strlen
(
challenge2
)
+
strlen
(
checksum
)
+
32
);
sprintf
(
buf
,
"RealChallenge2: %s, sd=%s"
,
challenge2
,
checksum
);
rtsp_schedule_field
(
rtsp_session
,
buf
);
buf
=
realloc
(
buf
,
strlen
(
session_id
)
+
32
);
sprintf
(
buf
,
"If-Match: %s"
,
session_id
);
rtsp_schedule_field
(
rtsp_session
,
buf
);
rtsp_schedule_field
(
rtsp_session
,
"Transport: x-pn-tng/tcp;mode=play,rtp/avp/tcp;unicast;mode=play"
);
buf
=
realloc
(
buf
,
strlen
(
mrl
)
+
32
);
sprintf
(
buf
,
"%s/streamid=0"
,
mrl
);
rtsp_request_setup
(
rtsp_session
,
buf
);
if
(
h
->
prop
->
num_streams
>
1
)
{
rtsp_schedule_field
(
rtsp_session
,
"Transport: x-pn-tng/tcp;mode=play,rtp/avp/tcp;unicast;mode=play"
);
if
(
!
rtsp_search_answers
(
rtsp_session
,
"ETag"
))
lprintf
(
"real: got no ETag!
\n
"
);
else
session_id
=
strdup
(
rtsp_search_answers
(
rtsp_session
,
"ETag"
));
lprintf
(
"Stream description size: %i
\n
"
,
size
);
description
=
(
char
*
)
malloc
(
sizeof
(
char
)
*
(
size
+
1
));
if
(
!
description
)
goto
error
;
if
(
rtsp_read_data
(
rtsp_session
,
description
,
size
)
<=
0
)
goto
error
;
description
[
size
]
=
0
;
fprintf
(
stderr
,
description
);
/* parse sdp (sdpplin) and create a header and a subscribe string */
subscribe
=
(
char
*
)
malloc
(
sizeof
(
char
)
*
256
);
if
(
!
subscribe
)
goto
error
;
strcpy
(
subscribe
,
"Subscribe: "
);
h
=
real_parse_sdp
(
description
,
&
subscribe
,
bandwidth
);
if
(
!
h
)
goto
error
;
rmff_fix_header
(
h
);
#if 0
fprintf("Title: %s\nCopyright: %s\nAuthor: %s\nStreams: %i\n",
h->cont->title, h->cont->copyright, h->cont->author, h->prop->num_streams);
#endif
/* setup our streams */
real_calc_response_and_checksum
(
challenge2
,
checksum
,
challenge1
);
buf
=
realloc
(
buf
,
strlen
(
challenge2
)
+
strlen
(
checksum
)
+
32
);
sprintf
(
buf
,
"RealChallenge2: %s, sd=%s"
,
challenge2
,
checksum
);
rtsp_schedule_field
(
rtsp_session
,
buf
);
buf
=
realloc
(
buf
,
strlen
(
session_id
)
+
32
);
sprintf
(
buf
,
"If-Match: %s"
,
session_id
);
rtsp_schedule_field
(
rtsp_session
,
buf
);
rtsp_schedule_field
(
rtsp_session
,
"Transport: x-pn-tng/tcp;mode=play,rtp/avp/tcp;unicast;mode=play"
);
buf
=
realloc
(
buf
,
strlen
(
mrl
)
+
32
);
sprintf
(
buf
,
"%s/streamid=
1
"
,
mrl
);
sprintf
(
buf
,
"%s/streamid=
0
"
,
mrl
);
rtsp_request_setup
(
rtsp_session
,
buf
);
}
/* set stream parameter (bandwidth) with our subscribe string */
rtsp_schedule_field
(
rtsp_session
,
subscribe
);
rtsp_request_setparameter
(
rtsp_session
,
NULL
);
/* and finally send a play request */
rtsp_schedule_field
(
rtsp_session
,
"Range: npt=0-"
);
rtsp_request_play
(
rtsp_session
,
NULL
);
free
(
subscribe
);
free
(
buf
);
return
h
;
if
(
h
->
prop
->
num_streams
>
1
)
{
rtsp_schedule_field
(
rtsp_session
,
"Transport: x-pn-tng/tcp;mode=play,rtp/avp/tcp;unicast;mode=play"
);
buf
=
realloc
(
buf
,
strlen
(
session_id
)
+
32
);
sprintf
(
buf
,
"If-Match: %s"
,
session_id
);
rtsp_schedule_field
(
rtsp_session
,
buf
);
buf
=
realloc
(
buf
,
strlen
(
mrl
)
+
32
);
sprintf
(
buf
,
"%s/streamid=1"
,
mrl
);
rtsp_request_setup
(
rtsp_session
,
buf
);
}
/* set stream parameter (bandwidth) with our subscribe string */
rtsp_schedule_field
(
rtsp_session
,
subscribe
);
rtsp_request_setparameter
(
rtsp_session
,
NULL
);
/* and finally send a play request */
rtsp_schedule_field
(
rtsp_session
,
"Range: npt=0-"
);
rtsp_request_play
(
rtsp_session
,
NULL
);
if
(
challenge1
)
free
(
challenge1
);
if
(
session_id
)
free
(
session_id
);
if
(
description
)
free
(
description
);
if
(
subscribe
)
free
(
subscribe
);
if
(
buf
)
free
(
buf
);
return
h
;
error:
if
(
h
)
rmff_free_header
(
h
);
if
(
challenge1
)
free
(
challenge1
);
if
(
session_id
)
free
(
session_id
);
if
(
description
)
free
(
description
);
if
(
subscribe
)
free
(
subscribe
);
if
(
buf
)
free
(
buf
);
return
NULL
;
}
modules/access/rtsp/real_rmff.c
View file @
66f1e9dd
...
...
@@ -43,7 +43,7 @@ static void rmff_dump_fileheader(rmff_fileheader_t *fileheader, char *buffer) {
fileheader
->
object_version
=
BE_16
(
&
fileheader
->
object_version
);
fileheader
->
file_version
=
BE_32
(
&
fileheader
->
file_version
);
fileheader
->
num_headers
=
BE_32
(
&
fileheader
->
num_headers
);
memcpy
(
buffer
,
fileheader
,
8
);
memcpy
(
&
buffer
[
8
],
&
fileheader
->
object_version
,
2
);
memcpy
(
&
buffer
[
10
],
&
fileheader
->
file_version
,
8
);
...
...
@@ -78,7 +78,7 @@ static void rmff_dump_prop(rmff_prop_t *prop, char *buffer) {
memcpy
(
&
buffer
[
10
],
&
prop
->
max_bit_rate
,
36
);
memcpy
(
&
buffer
[
46
],
&
prop
->
num_streams
,
2
);
memcpy
(
&
buffer
[
48
],
&
prop
->
flags
,
2
);
prop
->
size
=
BE_32
(
&
prop
->
size
);
prop
->
object_version
=
BE_16
(
&
prop
->
object_version
);
prop
->
max_bit_rate
=
BE_32
(
&
prop
->
max_bit_rate
);
...
...
@@ -123,7 +123,7 @@ static void rmff_dump_mdpr(rmff_mdpr_t *mdpr, char *buffer) {
memcpy
(
&
buffer
[
41
+
s1
],
&
mdpr
->
mime_type_size
,
1
);
s2
=
mdpr
->
mime_type_size
;
memcpy
(
&
buffer
[
42
+
s1
],
mdpr
->
mime_type
,
s2
);
mdpr
->
type_specific_len
=
BE_32
(
&
mdpr
->
type_specific_len
);
memcpy
(
&
buffer
[
42
+
s1
+
s2
],
&
mdpr
->
type_specific_len
,
4
);
mdpr
->
type_specific_len
=
BE_32
(
&
mdpr
->
type_specific_len
);
...
...
@@ -154,7 +154,7 @@ static void rmff_dump_cont(rmff_cont_t *cont, char *buffer) {
memcpy
(
buffer
,
cont
,
8
);
memcpy
(
&
buffer
[
8
],
&
cont
->
object_version
,
2
);
cont
->
title_len
=
BE_16
(
&
cont
->
title_len
);
memcpy
(
&
buffer
[
10
],
&
cont
->
title_len
,
2
);
cont
->
title_len
=
BE_16
(
&
cont
->
title_len
);
...
...
@@ -183,24 +183,25 @@ static void rmff_dump_cont(rmff_cont_t *cont, char *buffer) {
cont
->
object_id
=
BE_32
(
&
cont
->
object_id
);
}
static
void
rmff_dump_dataheader
(
rmff_data_t
*
data
,
char
*
buffer
)
{
if
(
!
data
)
return
;
data
->
object_id
=
BE_32
(
&
data
->
object_id
);
data
->
size
=
BE_32
(
&
data
->
size
);
data
->
object_version
=
BE_16
(
&
data
->
object_version
);
data
->
num_packets
=
BE_32
(
&
data
->
num_packets
);
data
->
next_data_header
=
BE_32
(
&
data
->
next_data_header
);
memcpy
(
buffer
,
data
,
8
);
memcpy
(
&
buffer
[
8
],
&
data
->
object_version
,
2
);
memcpy
(
&
buffer
[
10
],
&
data
->
num_packets
,
8
);
data
->
num_packets
=
BE_32
(
&
data
->
num_packets
);
data
->
next_data_header
=
BE_32
(
&
data
->
next_data_header
);
data
->
size
=
BE_32
(
&
data
->
size
);
data
->
object_version
=
BE_16
(
&
data
->
object_version
);
data
->
object_id
=
BE_32
(
&
data
->
object_id
);
static
void
rmff_dump_dataheader
(
rmff_data_t
*
data
,
char
*
buffer
)
{
if
(
!
data
)
return
;
data
->
object_id
=
BE_32
(
&
data
->
object_id
);
data
->
size
=
BE_32
(
&
data
->
size
);
data
->
object_version
=
BE_16
(
&
data
->
object_version
);
data
->
num_packets
=
BE_32
(
&
data
->
num_packets
);
data
->
next_data_header
=
BE_32
(
&
data
->
next_data_header
);
memcpy
(
buffer
,
data
,
8
);
memcpy
(
&
buffer
[
8
],
&
data
->
object_version
,
2
);
memcpy
(
&
buffer
[
10
],
&
data
->
num_packets
,
8
);
data
->
num_packets
=
BE_32
(
&
data
->
num_packets
);
data
->
next_data_header
=
BE_32
(
&
data
->
next_data_header
);
data
->
size
=
BE_32
(
&
data
->
size
);
data
->
object_version
=
BE_16
(
&
data
->
object_version
);
data
->
object_id
=
BE_32
(
&
data
->
object_id
);
}
int
rmff_dump_header
(
rmff_header_t
*
h
,
char
*
buffer
,
int
max
)
{
...
...
@@ -223,7 +224,7 @@ int rmff_dump_header(rmff_header_t *h, char *buffer, int max) {
stream
++
;
}
}
rmff_dump_dataheader
(
h
->
data
,
&
buffer
[
written
]);
written
+=
18
;
...
...
@@ -246,18 +247,19 @@ void rmff_dump_pheader(rmff_pheader_t *h, char *data) {
data
[
11
]
=
h
->
flags
;
}
rmff_fileheader_t
*
rmff_new_fileheader
(
uint32_t
num_headers
)
{
rmff_fileheader_t
*
fileheader
=
malloc
(
sizeof
(
rmff_fileheader_t
));
memset
(
fileheader
,
0
,
sizeof
(
rmff_fileheader_t
))
;
rmff_fileheader_t
*
rmff_new_fileheader
(
uint32_t
num_headers
)
{
rmff_fileheader_t
*
fileheader
=
malloc
(
sizeof
(
rmff_fileheader_t
));
if
(
!
filehandler
)
return
NULL
;
fileheader
->
object_id
=
RMF_TAG
;
fileheader
->
size
=
18
;
fileheader
->
object_version
=
0
;
fileheader
->
file_version
=
0
;
fileheader
->
num_headers
=
num_headers
;
memset
(
fileheader
,
0
,
sizeof
(
rmff_fileheader_t
));
fileheader
->
object_id
=
RMF_TAG
;
fileheader
->
size
=
18
;
fileheader
->
object_version
=
0
;
fileheader
->
file_version
=
0
;
fileheader
->
num_headers
=
num_headers
;
return
fileheader
;
return
fileheader
;
}
rmff_prop_t
*
rmff_new_prop
(
...
...
@@ -271,28 +273,28 @@ rmff_prop_t *rmff_new_prop (
uint32_t
index_offset
,
uint32_t
data_offset
,
uint16_t
num_streams
,
uint16_t
flags
)
{
rmff_prop_t
*
prop
=
malloc
(
sizeof
(
rmff_prop_t
));
memset
(
prop
,
0
,
sizeof
(
rmff_prop_t
))
;
prop
->
object_id
=
PROP_TAG
;
prop
->
size
=
50
;
prop
->
object_version
=
0
;
prop
->
max_bit_rate
=
max_bit_rate
;
prop
->
avg_bit_rate
=
avg_bit_rate
;
prop
->
max_packet_size
=
max_packet_size
;
prop
->
avg_packet_size
=
avg_packet_size
;
prop
->
num_packets
=
num_packets
;
prop
->
duration
=
duration
;
prop
->
preroll
=
preroll
;
prop
->
index_offset
=
index_offset
;
prop
->
data_offset
=
data_offset
;
prop
->
num_streams
=
num_streams
;
prop
->
flags
=
flags
;
return
prop
;
uint16_t
flags
)
{
rmff_prop_t
*
prop
=
malloc
(
sizeof
(
rmff_prop_t
));
if
(
!
prop
)
return
NULL
;
memset
(
prop
,
0
,
sizeof
(
rmff_prop_t
))
;
prop
->
object_id
=
PROP_TAG
;
prop
->
size
=
5
0
;
prop
->
object_version
=
0
;
prop
->
max_bit_rate
=
max_bit_rate
;
prop
->
avg_bit_rate
=
avg_bit_rate
;
prop
->
max_packet_size
=
max_packet_size
;
prop
->
avg_packet_size
=
avg_packet_size
;
prop
->
num_packets
=
num_packets
;
prop
->
duration
=
duration
;
prop
->
preroll
=
preroll
;
prop
->
index_offset
=
index_offset
;
prop
->
data_offset
=
data_offset
;
prop
->
num_streams
=
num_streams
;
prop
->
flags
=
flags
;
return
prop
;
}
rmff_mdpr_t
*
rmff_new_mdpr
(
...
...
@@ -307,304 +309,317 @@ rmff_mdpr_t *rmff_new_mdpr(
const
char
*
stream_name
,
const
char
*
mime_type
,
uint32_t
type_specific_len
,
const
char
*
type_specific_data
)
{
rmff_mdpr_t
*
mdpr
=
malloc
(
sizeof
(
rmff_mdpr_t
));
memset
(
mdpr
,
0
,
sizeof
(
rmff_mdpr_t
));
mdpr
->
object_id
=
MDPR_TAG
;
mdpr
->
object_version
=
0
;
mdpr
->
stream_number
=
stream_number
;
mdpr
->
max_bit_rate
=
max_bit_rate
;
mdpr
->
avg_bit_rate
=
avg_bit_rate
;
mdpr
->
max_packet_size
=
max_packet_size
;
mdpr
->
avg_packet_size
=
avg_packet_size
;
mdpr
->
start_time
=
start_time
;
mdpr
->
preroll
=
preroll
;
mdpr
->
duration
=
duration
;
mdpr
->
stream_name_size
=
0
;
if
(
stream_name
)
{
mdpr
->
stream_name
=
strdup
(
stream_name
);
mdpr
->
stream_name_size
=
strlen
(
stream_name
);
}
mdpr
->
mime_type_size
=
0
;
if
(
mime_type
)
{
mdpr
->
mime_type
=
strdup
(
mime_type
);
mdpr
->
mime_type_size
=
strlen
(
mime_type
);
}
mdpr
->
type_specific_len
=
type_specific_len
;
mdpr
->
type_specific_data
=
malloc
(
sizeof
(
char
)
*
type_specific_len
);
memcpy
(
mdpr
->
type_specific_data
,
type_specific_data
,
type_specific_len
);
mdpr
->
mlti_data
=
NULL
;
mdpr
->
size
=
mdpr
->
stream_name_size
+
mdpr
->
mime_type_size
+
mdpr
->
type_specific_len
+
46
;
return
mdpr
;
}
rmff_cont_t
*
rmff_new_cont
(
const
char
*
title
,
const
char
*
author
,
const
char
*
copyright
,
const
char
*
comment
)
{
rmff_cont_t
*
cont
=
malloc
(
sizeof
(
rmff_cont_t
));
memset
(
cont
,
0
,
sizeof
(
rmff_cont_t
));
cont
->
object_id
=
CONT_TAG
;
cont
->
object_version
=
0
;
cont
->
title
=
NULL
;
cont
->
author
=
NULL
;
cont
->
copyright
=
NULL
;
cont
->
comment
=
NULL
;
cont
->
title_len
=
0
;
cont
->
author_len
=
0
;
cont
->
copyright_len
=
0
;
cont
->
comment_len
=
0
;
if
(
title
)
{
cont
->
title_len
=
strlen
(
title
);
cont
->
title
=
strdup
(
title
);
}
if
(
author
)
{
cont
->
author_len
=
strlen
(
author
);
cont
->
author
=
strdup
(
author
);
}
if
(
copyright
)
{
cont
->
copyright_len
=
strlen
(
copyright
);
cont
->
copyright
=
strdup
(
copyright
);
}
if
(
comment
)
{
cont
->
comment_len
=
strlen
(
comment
);
cont
->
comment
=
strdup
(
comment
);
}
cont
->
size
=
cont
->
title_len
+
cont
->
author_len
+
cont
->
copyright_len
+
cont
->
comment_len
+
18
;
const
char
*
type_specific_data
)
{
rmff_mdpr_t
*
mdpr
=
malloc
(
sizeof
(
rmff_mdpr_t
));
if
(
!
mdpr
)
return
NULL
;
memset
(
mdpr
,
0
,
sizeof
(
rmff_mdpr_t
));
mdpr
->
object_id
=
MDPR_TAG
;
mdpr
->
object_version
=
0
;
mdpr
->
stream_number
=
stream_number
;
mdpr
->
max_bit_rate
=
max_bit_rate
;
mdpr
->
avg_bit_rate
=
avg_bit_rate
;
mdpr
->
max_packet_size
=
max_packet_size
;
mdpr
->
avg_packet_size
=
avg_packet_size
;
mdpr
->
start_time
=
start_time
;
mdpr
->
preroll
=
preroll
;
mdpr
->
duration
=
duration
;
mdpr
->
stream_name_size
=
0
;
if
(
stream_name
)
{
mdpr
->
stream_name
=
strdup
(
stream_name
);
mdpr
->
stream_name_size
=
strlen
(
stream_name
);
}
mdpr
->
mime_type_size
=
0
;
if
(
mime_type
)
{
mdpr
->
mime_type
=
strdup
(
mime_type
);
mdpr
->
mime_type_size
=
strlen
(
mime_type
);
}
mdpr
->
type_specific_len
=
type_specific_len
;
return
cont
;
mdpr
->
type_specific_data
=
malloc
(
sizeof
(
char
)
*
type_specific_len
);
if
(
!
mdpr
->
type_specific_data
)
{
if
(
mdpr
->
stream_name
)
free
(
mdpr
->
stream_name
);
free
(
mdpr
);
return
NULL
;
}
memcpy
(
mdpr
->
type_specific_data
,
type_specific_data
,
type_specific_len
);
mdpr
->
mlti_data
=
NULL
;
mdpr
->
size
=
mdpr
->
stream_name_size
+
mdpr
->
mime_type_size
+
mdpr
->
type_specific_len
+
46
;
return
mdpr
;
}
rmff_data_t
*
rmff_new_dataheader
(
uint32_t
num_packets
,
uint32_t
next_data_header
)
{
rmff_cont_t
*
rmff_new_cont
(
const
char
*
title
,
const
char
*
author
,
const
char
*
copyright
,
const
char
*
comment
)
{
rmff_cont_t
*
cont
=
malloc
(
sizeof
(
rmff_cont_t
));
if
(
!
cont
)
return
NULL
;
memset
(
cont
,
0
,
sizeof
(
rmff_cont_t
));
cont
->
object_id
=
CONT_TAG
;
cont
->
object_version
=
0
;
cont
->
title
=
NULL
;
cont
->
author
=
NULL
;
cont
->
copyright
=
NULL
;
cont
->
comment
=
NULL
;
cont
->
title_len
=
0
;
cont
->
author_len
=
0
;
cont
->
copyright_len
=
0
;
cont
->
comment_len
=
0
;
if
(
title
)
{
cont
->
title_len
=
strlen
(
title
);
cont
->
title
=
strdup
(
title
);
}
if
(
author
)
{
cont
->
author_len
=
strlen
(
author
);
cont
->
author
=
strdup
(
author
);
}
if
(
copyright
)
{
cont
->
copyright_len
=
strlen
(
copyright
);
cont
->
copyright
=
strdup
(
copyright
);
}
if
(
comment
)
{
cont
->
comment_len
=
strlen
(
comment
);
cont
->
comment
=
strdup
(
comment
);
}
cont
->
size
=
cont
->
title_len
+
cont
->
author_len
+
cont
->
copyright_len
+
cont
->
comment_len
+
18
;
return
cont
;
}
rmff_data_t
*
data
=
malloc
(
sizeof
(
rmff_data_t
));
memset
(
data
,
0
,
sizeof
(
rmff_data_t
));
rmff_data_t
*
rmff_new_dataheader
(
uint32_t
num_packets
,
uint32_t
next_data_header
)
{
rmff_data_t
*
data
=
malloc
(
sizeof
(
rmff_data_t
));
if
(
!
data
)
return
NULL
;
data
->
object_id
=
DATA_TAG
;
data
->
size
=
18
;
data
->
object_version
=
0
;
data
->
num_packets
=
num_packets
;
data
->
next_data_header
=
next_data_header
;
memset
(
data
,
0
,
sizeof
(
rmff_data_t
));
data
->
object_id
=
DATA_TAG
;
data
->
size
=
18
;
data
->
object_version
=
0
;
data
->
num_packets
=
num_packets
;
data
->
next_data_header
=
next_data_header
;
return
data
;
return
data
;
}
void
rmff_print_header
(
rmff_header_t
*
h
)
{
void
rmff_print_header
(
rmff_header_t
*
h
)
{
rmff_mdpr_t
**
stream
;
if
(
!
h
)
{
printf
(
"rmff_print_header: NULL given
\n
"
);
return
;
}
if
(
h
->
fileheader
)
{
printf
(
"
\n
FILE:
\n
"
);
printf
(
"file version : %d
\n
"
,
h
->
fileheader
->
file_version
);
printf
(
"number of headers : %d
\n
"
,
h
->
fileheader
->
num_headers
);
}
if
(
h
->
cont
)
{
printf
(
"
\n
CONTENT:
\n
"
);
printf
(
"title : %s
\n
"
,
h
->
cont
->
title
);
printf
(
"author : %s
\n
"
,
h
->
cont
->
author
);
printf
(
"copyright : %s
\n
"
,
h
->
cont
->
copyright
);
printf
(
"comment : %s
\n
"
,
h
->
cont
->
comment
);
}
if
(
h
->
prop
)
{
printf
(
"
\n
STREAM PROPERTIES:
\n
"
);
printf
(
"bit rate (max/avg) : %i/%i
\n
"
,
h
->
prop
->
max_bit_rate
,
h
->
prop
->
avg_bit_rate
);
printf
(
"packet size (max/avg) : %i/%i bytes
\n
"
,
h
->
prop
->
max_packet_size
,
h
->
prop
->
avg_packet_size
);
printf
(
"packets : %i
\n
"
,
h
->
prop
->
num_packets
);
printf
(
"duration : %i ms
\n
"
,
h
->
prop
->
duration
);
printf
(
"pre-buffer : %i ms
\n
"
,
h
->
prop
->
preroll
);
printf
(
"index offset : %i bytes
\n
"
,
h
->
prop
->
index_offset
);
printf
(
"data offset : %i bytes
\n
"
,
h
->
prop
->
data_offset
);
printf
(
"media streams : %i
\n
"
,
h
->
prop
->
num_streams
);
printf
(
"flags : "
);
if
(
h
->
prop
->
flags
&
PN_SAVE_ENABLED
)
printf
(
"save_enabled "
);
if
(
h
->
prop
->
flags
&
PN_PERFECT_PLAY_ENABLED
)
printf
(
"perfect_play_enabled "
);
if
(
h
->
prop
->
flags
&
PN_LIVE_BROADCAST
)
printf
(
"live_broadcast "
);
printf
(
"
\n
"
);
}
stream
=
h
->
streams
;
if
(
stream
)
{
while
(
*
stream
)
if
(
!
h
)
{
printf
(
"
\n
STREAM %i:
\n
"
,
(
*
stream
)
->
stream_number
);
printf
(
"stream name [mime type] : %s [%s]
\n
"
,
(
*
stream
)
->
stream_name
,
(
*
stream
)
->
mime_type
);
printf
(
"bit rate (max/avg) : %i/%i
\n
"
,
(
*
stream
)
->
max_bit_rate
,
(
*
stream
)
->
avg_bit_rate
);
printf
(
"packet size (max/avg) : %i/%i bytes
\n
"
,
(
*
stream
)
->
max_packet_size
,
(
*
stream
)
->
avg_packet_size
);
printf
(
"start time : %i
\n
"
,
(
*
stream
)
->
start_time
);
printf
(
"pre-buffer : %i ms
\n
"
,
(
*
stream
)
->
preroll
);
printf
(
"duration : %i ms
\n
"
,
(
*
stream
)
->
duration
);
printf
(
"type specific data:
\n
"
);
stream
++
;
printf
(
"rmff_print_header: NULL given
\n
"
);
return
;
}
if
(
h
->
fileheader
)
{
printf
(
"
\n
FILE:
\n
"
);
printf
(
"file version : %d
\n
"
,
h
->
fileheader
->
file_version
);
printf
(
"number of headers : %d
\n
"
,
h
->
fileheader
->
num_headers
);
}
if
(
h
->
cont
)
{
printf
(
"
\n
CONTENT:
\n
"
);
printf
(
"title : %s
\n
"
,
h
->
cont
->
title
);
printf
(
"author : %s
\n
"
,
h
->
cont
->
author
);
printf
(
"copyright : %s
\n
"
,
h
->
cont
->
copyright
);
printf
(
"comment : %s
\n
"
,
h
->
cont
->
comment
);
}
if
(
h
->
prop
)
{
printf
(
"
\n
STREAM PROPERTIES:
\n
"
);
printf
(
"bit rate (max/avg) : %i/%i
\n
"
,
h
->
prop
->
max_bit_rate
,
h
->
prop
->
avg_bit_rate
);
printf
(
"packet size (max/avg) : %i/%i bytes
\n
"
,
h
->
prop
->
max_packet_size
,
h
->
prop
->
avg_packet_size
);
printf
(
"packets : %i
\n
"
,
h
->
prop
->
num_packets
);
printf
(
"duration : %i ms
\n
"
,
h
->
prop
->
duration
);
printf
(
"pre-buffer : %i ms
\n
"
,
h
->
prop
->
preroll
);
printf
(
"index offset : %i bytes
\n
"
,
h
->
prop
->
index_offset
);
printf
(
"data offset : %i bytes
\n
"
,
h
->
prop
->
data_offset
);
printf
(
"media streams : %i
\n
"
,
h
->
prop
->
num_streams
);
printf
(
"flags : "
);
if
(
h
->
prop
->
flags
&
PN_SAVE_ENABLED
)
printf
(
"save_enabled "
);
if
(
h
->
prop
->
flags
&
PN_PERFECT_PLAY_ENABLED
)
printf
(
"perfect_play_enabled "
);
if
(
h
->
prop
->
flags
&
PN_LIVE_BROADCAST
)
printf
(
"live_broadcast "
);
printf
(
"
\n
"
);
}
stream
=
h
->
streams
;
if
(
stream
)
{
while
(
*
stream
)
{
printf
(
"
\n
STREAM %i:
\n
"
,
(
*
stream
)
->
stream_number
);
printf
(
"stream name [mime type] : %s [%s]
\n
"
,
(
*
stream
)
->
stream_name
,
(
*
stream
)
->
mime_type
);
printf
(
"bit rate (max/avg) : %i/%i
\n
"
,
(
*
stream
)
->
max_bit_rate
,
(
*
stream
)
->
avg_bit_rate
);
printf
(
"packet size (max/avg) : %i/%i bytes
\n
"
,
(
*
stream
)
->
max_packet_size
,
(
*
stream
)
->
avg_packet_size
);
printf
(
"start time : %i
\n
"
,
(
*
stream
)
->
start_time
);
printf
(
"pre-buffer : %i ms
\n
"
,
(
*
stream
)
->
preroll
);
printf
(
"duration : %i ms
\n
"
,
(
*
stream
)
->
duration
);
printf
(
"type specific data:
\n
"
);
stream
++
;
}
}
if
(
h
->
data
)
{
printf
(
"
\n
DATA:
\n
"
);
printf
(
"size : %i
\n
"
,
h
->
data
->
size
);
printf
(
"packets : %i
\n
"
,
h
->
data
->
num_packets
);
printf
(
"next DATA : 0x%08x
\n
"
,
h
->
data
->
next_data_header
);
}
}
if
(
h
->
data
)
{
printf
(
"
\n
DATA:
\n
"
);
printf
(
"size : %i
\n
"
,
h
->
data
->
size
);
printf
(
"packets : %i
\n
"
,
h
->
data
->
num_packets
);
printf
(
"next DATA : 0x%08x
\n
"
,
h
->
data
->
next_data_header
);
}
}
void
rmff_fix_header
(
rmff_header_t
*
h
)
{
int
num_headers
=
0
;
int
header_size
=
0
;
rmff_mdpr_t
**
streams
;
int
num_streams
=
0
;
if
(
!
h
)
{
lprintf
(
"rmff_fix_header: fatal: no header given.
\n
"
);
return
;
}
void
rmff_fix_header
(
rmff_header_t
*
h
)
{
int
num_headers
=
0
;
int
header_size
=
0
;
rmff_mdpr_t
**
streams
;
int
num_streams
=
0
;
if
(
!
h
->
streams
)
{
lprintf
(
"rmff_fix_header: warning: no MDPR chunks
\n
"
);
}
else
{
streams
=
h
->
streams
;
while
(
*
streams
)
if
(
!
h
)
{
num_streams
++
;
num_headers
++
;
header_size
+=
(
*
streams
)
->
size
;
streams
++
;
lprintf
(
"rmff_fix_header: fatal: no header given.
\n
"
);
return
;
}
}
if
(
h
->
prop
)
{
if
(
h
->
prop
->
size
!=
50
)
if
(
!
h
->
streams
)
{
lprintf
(
"rmff_fix_header: correcting prop.size from %i to %i
\n
"
,
h
->
prop
->
size
,
50
);
h
->
prop
->
size
=
50
;
lprintf
(
"rmff_fix_header: warning: no MDPR chunks
\n
"
);
}
if
(
h
->
prop
->
num_streams
!=
num_streams
)
else
{
lprintf
(
"rmff_fix_header: correcting prop.num_streams from %i to %i
\n
"
,
h
->
prop
->
num_streams
,
num_streams
);
streams
=
h
->
streams
;
while
(
*
streams
)
{
num_streams
++
;
num_headers
++
;
header_size
+=
(
*
streams
)
->
size
;
streams
++
;
}
}
if
(
h
->
prop
)
{
if
(
h
->
prop
->
size
!=
50
)
{
lprintf
(
"rmff_fix_header: correcting prop.size from %i to %i
\n
"
,
h
->
prop
->
size
,
50
);
h
->
prop
->
size
=
50
;
}
if
(
h
->
prop
->
num_streams
!=
num_streams
)
{
lprintf
(
"rmff_fix_header: correcting prop.num_streams from %i to %i
\n
"
,
h
->
prop
->
num_streams
,
num_streams
);
h
->
prop
->
num_streams
=
num_streams
;
}
num_headers
++
;
header_size
+=
50
;
}
else
lprintf
(
"rmff_fix_header: warning: no PROP chunk.
\n
"
);
h
->
prop
->
num_streams
=
num_streams
;
if
(
h
->
cont
)
{
num_headers
++
;
header_size
+=
h
->
cont
->
size
;
}
num_headers
++
;
header_size
+=
50
;
}
else
lprintf
(
"rmff_fix_header: warning: no PROP chunk.
\n
"
);
else
lprintf
(
"rmff_fix_header: warning: no CONT chunk.
\n
"
);
if
(
h
->
cont
)
{
if
(
!
h
->
data
)
{
lprintf
(
"rmff_fix_header: no DATA chunk, creating one
\n
"
);
h
->
data
=
malloc
(
sizeof
(
rmff_data_t
));
if
(
h
->
data
)
{
memset
(
h
->
data
,
0
,
sizeof
(
rmff_data_t
));
h
->
data
->
object_id
=
DATA_TAG
;
h
->
data
->
object_version
=
0
;
h
->
data
->
size
=
34
;
h
->
data
->
num_packets
=
0
;
h
->
data
->
next_data_header
=
0
;
}
}
num_headers
++
;
header_size
+=
h
->
cont
->
size
;
}
else
lprintf
(
"rmff_fix_header: warning: no CONT chunk.
\n
"
);
if
(
!
h
->
data
)
{
lprintf
(
"rmff_fix_header: no DATA chunk, creating one
\n
"
);
h
->
data
=
malloc
(
sizeof
(
rmff_data_t
));
memset
(
h
->
data
,
0
,
sizeof
(
rmff_data_t
));
h
->
data
->
object_id
=
DATA_TAG
;
h
->
data
->
object_version
=
0
;
h
->
data
->
size
=
34
;
h
->
data
->
num_packets
=
0
;
h
->
data
->
next_data_header
=
0
;
}
num_headers
++
;
if
(
!
h
->
fileheader
)
{
lprintf
(
"rmff_fix_header: no fileheader, creating one"
);
h
->
fileheader
=
malloc
(
sizeof
(
rmff_fileheader_t
));
memset
(
h
->
fileheader
,
0
,
sizeof
(
rmff_fileheader_t
));
h
->
fileheader
->
object_id
=
RMF_TAG
;
h
->
fileheader
->
size
=
34
;
h
->
fileheader
->
object_version
=
0
;
h
->
fileheader
->
file_version
=
0
;
h
->
fileheader
->
num_headers
=
num_headers
+
1
;
}
header_size
+=
h
->
fileheader
->
size
;
num_headers
++
;
if
(
h
->
fileheader
->
num_headers
!=
num_headers
)
{
lprintf
(
"rmff_fix_header: setting num_headers from %i to %i
\n
"
,
h
->
fileheader
->
num_headers
,
num_headers
);
h
->
fileheader
->
num_headers
=
num_headers
;
}
if
(
h
->
prop
)
{
if
(
h
->
prop
->
data_offset
!=
header_size
)
{
lprintf
(
"rmff_fix_header: setting prop.data_offset from %i to %i
\n
"
,
h
->
prop
->
data_offset
,
header_size
);
h
->
prop
->
data_offset
=
header_size
;
if
(
!
h
->
fileheader
)
{
lprintf
(
"rmff_fix_header: no fileheader, creating one"
);
h
->
fileheader
=
malloc
(
sizeof
(
rmff_fileheader_t
));
if
(
h
->
fileheader
)
{
memset
(
h
->
fileheader
,
0
,
sizeof
(
rmff_fileheader_t
));
h
->
fileheader
->
object_id
=
RMF_TAG
;
h
->
fileheader
->
size
=
34
;
h
->
fileheader
->
object_version
=
0
;
h
->
fileheader
->
file_version
=
0
;
h
->
fileheader
->
num_headers
=
num_headers
+
1
;
}
}
if
(
h
->
prop
->
num_packets
==
0
)
{
int
p
=
(
int
)(
h
->
prop
->
avg_bit_rate
/
8
.
0
*
(
h
->
prop
->
duration
/
1000
.
0
)
/
h
->
prop
->
avg_packet_size
);
lprintf
(
"rmff_fix_header: assuming prop.num_packets=%i
\n
"
,
p
);
header_size
+=
h
->
fileheader
->
size
;
num_headers
++
;
h
->
prop
->
num_packets
=
p
;
if
(
h
->
fileheader
->
num_headers
!=
num_headers
)
{
lprintf
(
"rmff_fix_header: setting num_headers from %i to %i
\n
"
,
h
->
fileheader
->
num_headers
,
num_headers
);
h
->
fileheader
->
num_headers
=
num_headers
;
}
if
(
h
->
data
->
num_packets
==
0
)
{
lprintf
(
"rmff_fix_header: assuming data.num_packets=%i
\n
"
,
h
->
prop
->
num_packets
);
h
->
data
->
num_packets
=
h
->
prop
->
num_packets
;
if
(
h
->
prop
)
{
if
(
h
->
prop
->
data_offset
!=
header_size
)
{
lprintf
(
"rmff_fix_header: setting prop.data_offset from %i to %i
\n
"
,
h
->
prop
->
data_offset
,
header_size
);
h
->
prop
->
data_offset
=
header_size
;
}
if
(
h
->
prop
->
num_packets
==
0
)
{
int
p
=
(
int
)(
h
->
prop
->
avg_bit_rate
/
8
.
0
*
(
h
->
prop
->
duration
/
1000
.
0
)
/
h
->
prop
->
avg_packet_size
);
lprintf
(
"rmff_fix_header: assuming prop.num_packets=%i
\n
"
,
p
);
h
->
prop
->
num_packets
=
p
;
}
if
(
h
->
data
->
num_packets
==
0
)
{
lprintf
(
"rmff_fix_header: assuming data.num_packets=%i
\n
"
,
h
->
prop
->
num_packets
);
h
->
data
->
num_packets
=
h
->
prop
->
num_packets
;
}
lprintf
(
"rmff_fix_header: assuming data.size=%i
\n
"
,
h
->
prop
->
num_packets
*
h
->
prop
->
avg_packet_size
);
h
->
data
->
size
=
h
->
prop
->
num_packets
*
h
->
prop
->
avg_packet_size
;
}
lprintf
(
"rmff_fix_header: assuming data.size=%i
\n
"
,
h
->
prop
->
num_packets
*
h
->
prop
->
avg_packet_size
);
h
->
data
->
size
=
h
->
prop
->
num_packets
*
h
->
prop
->
avg_packet_size
;
}
}
int
rmff_get_header_size
(
rmff_header_t
*
h
)
{
if
(
!
h
)
return
0
;
if
(
!
h
->
prop
)
return
-
1
;
return
h
->
prop
->
data_offset
+
18
;
int
rmff_get_header_size
(
rmff_header_t
*
h
)
{
if
(
!
h
)
return
0
;
if
(
!
h
->
prop
)
return
-
1
;
return
h
->
prop
->
data_offset
+
18
;
}
void
rmff_free_header
(
rmff_header_t
*
h
)
{
void
rmff_free_header
(
rmff_header_t
*
h
)
{
if
(
!
h
)
return
;
if
(
!
h
)
return
;
if
(
h
->
fileheader
)
free
(
h
->
fileheader
);
if
(
h
->
prop
)
free
(
h
->
prop
);
if
(
h
->
data
)
free
(
h
->
data
);
if
(
h
->
cont
)
{
free
(
h
->
cont
->
title
);
free
(
h
->
cont
->
author
);
free
(
h
->
cont
->
copyright
);
free
(
h
->
cont
->
comment
);
free
(
h
->
cont
);
}
if
(
h
->
streams
)
{
rmff_mdpr_t
**
s
=
h
->
streams
;
while
(
*
s
)
{
free
((
*
s
)
->
stream_name
);
free
((
*
s
)
->
mime_type
);
free
((
*
s
)
->
type_specific_data
);
free
(
*
s
);
s
++
;
if
(
h
->
fileheader
)
free
(
h
->
fileheader
);
if
(
h
->
prop
)
free
(
h
->
prop
);
if
(
h
->
data
)
free
(
h
->
data
);
if
(
h
->
cont
)
{
free
(
h
->
cont
->
title
);
free
(
h
->
cont
->
author
);
free
(
h
->
cont
->
copyright
);
free
(
h
->
cont
->
comment
);
free
(
h
->
cont
);
}
free
(
h
->
streams
);
}
free
(
h
);
if
(
h
->
streams
)
{
rmff_mdpr_t
**
s
=
h
->
streams
;
while
(
*
s
)
{
free
((
*
s
)
->
stream_name
);
free
((
*
s
)
->
mime_type
);
free
((
*
s
)
->
type_specific_data
);
free
(
*
s
);
s
++
;
}
free
(
h
->
streams
);
}
free
(
h
);
}
modules/access/rtsp/real_rmff.h
View file @
66f1e9dd
...
...
@@ -82,7 +82,6 @@ typedef struct {
uint32_t
data_offset
;
uint16_t
num_streams
;
uint16_t
flags
;
}
rmff_prop_t
;
typedef
struct
{
...
...
@@ -125,11 +124,11 @@ typedef struct {
char
*
copyright
;
uint16_t
comment_len
;
char
*
comment
;
}
rmff_cont_t
;
typedef
struct
{
uint32_t
object_id
;
uint32_t
size
;
uint16_t
object_version
;
...
...
@@ -162,7 +161,7 @@ typedef struct {
/*
* constructors for header structs
*/
rmff_fileheader_t
*
rmff_new_fileheader
(
uint32_t
num_headers
);
rmff_prop_t
*
rmff_new_prop
(
...
...
modules/access/rtsp/real_sdpplin.c
View file @
66f1e9dd
...
...
@@ -31,280 +31,297 @@
static
char
*
b64_decode
(
const
char
*
in
,
char
*
out
,
int
*
size
)
{
char
dtable
[
256
];
/* Encode / decode table */
int
i
,
j
,
k
;
char
dtable
[
256
];
/* Encode / decode table */
int
i
,
j
,
k
;
for
(
i
=
0
;
i
<
255
;
i
++
)
{
dtable
[
i
]
=
0x80
;
}
for
(
i
=
'A'
;
i
<=
'Z'
;
i
++
)
{
dtable
[
i
]
=
0
+
(
i
-
'A'
);
}
for
(
i
=
'a'
;
i
<=
'z'
;
i
++
)
{
dtable
[
i
]
=
26
+
(
i
-
'a'
);
}
for
(
i
=
'0'
;
i
<=
'9'
;
i
++
)
{
dtable
[
i
]
=
52
+
(
i
-
'0'
);
}
dtable
[
'+'
]
=
62
;
dtable
[
'/'
]
=
63
;
dtable
[
'='
]
=
0
;
k
=
0
;
/*CONSTANTCONDITION*/
for
(
j
=
0
;
j
<
strlen
(
in
);
j
+=
4
)
{
char
a
[
4
],
b
[
4
];
for
(
i
=
0
;
i
<
4
;
i
++
)
{
int
c
=
in
[
i
+
j
];
if
(
dtable
[
c
]
&
0x80
)
{
printf
(
"Illegal character '%c' in input.
\n
"
,
c
);
exit
(
1
);
}
a
[
i
]
=
(
char
)
c
;
b
[
i
]
=
(
char
)
dtable
[
c
];
for
(
i
=
0
;
i
<
255
;
i
++
)
{
dtable
[
i
]
=
0x80
;
}
for
(
i
=
'A'
;
i
<=
'Z'
;
i
++
)
{
dtable
[
i
]
=
0
+
(
i
-
'A'
);
}
//xine_buffer_ensure_size(out, k+3);
out
[
k
++
]
=
(
b
[
0
]
<<
2
)
|
(
b
[
1
]
>>
4
);
out
[
k
++
]
=
(
b
[
1
]
<<
4
)
|
(
b
[
2
]
>>
2
);
out
[
k
++
]
=
(
b
[
2
]
<<
6
)
|
b
[
3
];
i
=
a
[
2
]
==
'='
?
1
:
(
a
[
3
]
==
'='
?
2
:
3
);
if
(
i
<
3
)
{
out
[
k
]
=
0
;
*
size
=
k
;
return
out
;
for
(
i
=
'a'
;
i
<=
'z'
;
i
++
)
{
dtable
[
i
]
=
26
+
(
i
-
'a'
);
}
}
out
[
k
]
=
0
;
*
size
=
k
;
return
out
;
for
(
i
=
'0'
;
i
<=
'9'
;
i
++
)
{
dtable
[
i
]
=
52
+
(
i
-
'0'
);
}
dtable
[
'+'
]
=
62
;
dtable
[
'/'
]
=
63
;
dtable
[
'='
]
=
0
;
k
=
0
;
/*CONSTANTCONDITION*/
for
(
j
=
0
;
j
<
strlen
(
in
);
j
+=
4
)
{
char
a
[
4
],
b
[
4
];
for
(
i
=
0
;
i
<
4
;
i
++
)
{
int
c
=
in
[
i
+
j
];
if
(
dtable
[
c
]
&
0x80
)
{
printf
(
"Illegal character '%c' in input.
\n
"
,
c
);
exit
(
1
);
}
a
[
i
]
=
(
char
)
c
;
b
[
i
]
=
(
char
)
dtable
[
c
];
}
//xine_buffer_ensure_size(out, k+3);
out
[
k
++
]
=
(
b
[
0
]
<<
2
)
|
(
b
[
1
]
>>
4
);
out
[
k
++
]
=
(
b
[
1
]
<<
4
)
|
(
b
[
2
]
>>
2
);
out
[
k
++
]
=
(
b
[
2
]
<<
6
)
|
b
[
3
];
i
=
a
[
2
]
==
'='
?
1
:
(
a
[
3
]
==
'='
?
2
:
3
);
if
(
i
<
3
)
{
out
[
k
]
=
0
;
*
size
=
k
;
return
out
;
}
}
out
[
k
]
=
0
;
*
size
=
k
;
return
out
;
}
static
char
*
nl
(
char
*
data
)
{
char
*
nlptr
=
(
data
)
?
strchr
(
data
,
'\n'
)
:
NULL
;
return
(
nlptr
)
?
nlptr
+
1
:
NULL
;
static
char
*
nl
(
char
*
data
)
{
char
*
nlptr
=
(
data
)
?
strchr
(
data
,
'\n'
)
:
NULL
;
return
(
nlptr
)
?
nlptr
+
1
:
NULL
;
}
static
int
filter
(
const
char
*
in
,
const
char
*
filter
,
char
**
out
)
{
static
int
filter
(
const
char
*
in
,
const
char
*
filter
,
char
**
out
)
{
int
flen
=
strlen
(
filter
);
int
len
;
if
(
!
in
)
return
0
;
len
=
(
strchr
(
in
,
'\n'
))
?
strchr
(
in
,
'\n'
)
-
in
:
strlen
(
in
);
if
(
!
strncmp
(
in
,
filter
,
flen
))
{
if
(
in
[
flen
]
==
'"'
)
flen
++
;
if
(
in
[
len
-
1
]
==
13
)
len
--
;
if
(
in
[
len
-
1
]
==
'"'
)
len
--
;
memcpy
(
*
out
,
in
+
flen
,
len
-
flen
+
1
);
(
*
out
)[
len
-
flen
]
=
0
;
return
len
-
flen
;
}
int
flen
=
strlen
(
filter
);
int
len
;
if
(
!
in
)
return
0
;
len
=
(
strchr
(
in
,
'\n'
))
?
strchr
(
in
,
'\n'
)
-
in
:
strlen
(
in
);
if
(
!
strncmp
(
in
,
filter
,
flen
))
{
if
(
in
[
flen
]
==
'"'
)
flen
++
;
if
(
in
[
len
-
1
]
==
13
)
len
--
;
if
(
in
[
len
-
1
]
==
'"'
)
len
--
;
memcpy
(
*
out
,
in
+
flen
,
len
-
flen
+
1
);
(
*
out
)[
len
-
flen
]
=
0
;
return
len
-
flen
;
}
return
0
;
}
static
sdpplin_stream_t
*
sdpplin_parse_stream
(
char
**
data
)
{
sdpplin_stream_t
*
desc
=
malloc
(
sizeof
(
sdpplin_stream_t
));
char
*
buf
=
malloc
(
32000
);
char
*
decoded
=
malloc
(
32000
);
int
handled
;
memset
(
desc
,
0
,
sizeof
(
sdpplin_stream_t
));
if
(
filter
(
*
data
,
"m="
,
&
buf
))
{
desc
->
id
=
strdup
(
buf
);
}
else
{
lprintf
(
"sdpplin: no m= found.
\n
"
);
free
(
desc
);
free
(
buf
);
return
NULL
;
}
*
data
=
nl
(
*
data
);
while
(
*
data
&&
**
data
&&
*
data
[
0
]
!=
'm'
)
{
handled
=
0
;
if
(
filter
(
*
data
,
"a=control:streamid="
,
&
buf
))
{
desc
->
stream_id
=
atoi
(
buf
);
handled
=
1
;
*
data
=
nl
(
*
data
);
}
if
(
filter
(
*
data
,
"a=MaxBitRate:integer;"
,
&
buf
))
{
desc
->
max_bit_rate
=
atoi
(
buf
);
if
(
!
desc
->
avg_bit_rate
)
desc
->
avg_bit_rate
=
desc
->
max_bit_rate
;
handled
=
1
;
*
data
=
nl
(
*
data
);
}
if
(
filter
(
*
data
,
"a=MaxPacketSize:integer;"
,
&
buf
))
{
desc
->
max_packet_size
=
atoi
(
buf
);
if
(
!
desc
->
avg_packet_size
)
desc
->
avg_packet_size
=
desc
->
max_packet_size
;
handled
=
1
;
*
data
=
nl
(
*
data
);
}
if
(
filter
(
*
data
,
"a=StartTime:integer;"
,
&
buf
))
{
desc
->
start_time
=
atoi
(
buf
);
handled
=
1
;
*
data
=
nl
(
*
data
);
}
if
(
filter
(
*
data
,
"a=Preroll:integer;"
,
&
buf
))
{
desc
->
preroll
=
atoi
(
buf
);
handled
=
1
;
*
data
=
nl
(
*
data
);
}
if
(
filter
(
*
data
,
"a=length:npt="
,
&
buf
))
{
desc
->
duration
=
(
uint32_t
)(
atof
(
buf
)
*
1000
);
handled
=
1
;
*
data
=
nl
(
*
data
);
}
if
(
filter
(
*
data
,
"a=StreamName:string;"
,
&
buf
))
{
desc
->
stream_name
=
strdup
(
buf
);
desc
->
stream_name_size
=
strlen
(
desc
->
stream_name
);
handled
=
1
;
*
data
=
nl
(
*
data
);
}
static
sdpplin_stream_t
*
sdpplin_parse_stream
(
char
**
data
)
{
sdpplin_stream_t
*
desc
=
malloc
(
sizeof
(
sdpplin_stream_t
));
char
*
buf
=
malloc
(
32000
);
char
*
decoded
=
malloc
(
32000
);
int
handled
;
if
(
filter
(
*
data
,
"a=mimetype:string;"
,
&
buf
))
{
desc
->
mime_type
=
strdup
(
buf
);
desc
->
mime_type_size
=
strlen
(
desc
->
mime_type
);
handled
=
1
;
*
data
=
nl
(
*
data
);
}
if
(
!
desc
)
goto
error
;
memset
(
desc
,
0
,
sizeof
(
sdpplin_stream_t
));
if
(
filter
(
*
data
,
"a=OpaqueData:buffer;"
,
&
buf
))
{
decoded
=
b64_decode
(
buf
,
decoded
,
&
(
desc
->
mlti_data_size
));
desc
->
mlti_data
=
malloc
(
sizeof
(
char
)
*
desc
->
mlti_data_size
);
memcpy
(
desc
->
mlti_data
,
decoded
,
desc
->
mlti_data_size
);
handled
=
1
;
*
data
=
nl
(
*
data
);
lprintf
(
"mlti_data_size: %i
\n
"
,
desc
->
mlti_data_size
);
if
(
filter
(
*
data
,
"m="
,
&
buf
))
{
desc
->
id
=
strdup
(
buf
);
}
if
(
filter
(
*
data
,
"a=ASMRuleBook:string;"
,
&
buf
))
{
desc
->
asm_rule_book
=
strdup
(
buf
);
handled
=
1
;
*
data
=
nl
(
*
data
);
else
{
lprintf
(
"sdpplin: no m= found.
\n
"
);
if
(
decoded
)
free
(
decoded
);
if
(
desc
)
free
(
desc
);
if
(
buf
)
free
(
buf
);
return
NULL
;
}
if
(
!
handled
)
{
*
data
=
nl
(
*
data
);
while
(
*
data
&&
**
data
&&
*
data
[
0
]
!=
'm'
)
{
handled
=
0
;
if
(
filter
(
*
data
,
"a=control:streamid="
,
&
buf
))
{
desc
->
stream_id
=
atoi
(
buf
);
handled
=
1
;
*
data
=
nl
(
*
data
);
}
if
(
filter
(
*
data
,
"a=MaxBitRate:integer;"
,
&
buf
))
{
desc
->
max_bit_rate
=
atoi
(
buf
);
if
(
!
desc
->
avg_bit_rate
)
desc
->
avg_bit_rate
=
desc
->
max_bit_rate
;
handled
=
1
;
*
data
=
nl
(
*
data
);
}
if
(
filter
(
*
data
,
"a=MaxPacketSize:integer;"
,
&
buf
))
{
desc
->
max_packet_size
=
atoi
(
buf
);
if
(
!
desc
->
avg_packet_size
)
desc
->
avg_packet_size
=
desc
->
max_packet_size
;
handled
=
1
;
*
data
=
nl
(
*
data
);
}
if
(
filter
(
*
data
,
"a=StartTime:integer;"
,
&
buf
))
{
desc
->
start_time
=
atoi
(
buf
);
handled
=
1
;
*
data
=
nl
(
*
data
);
}
if
(
filter
(
*
data
,
"a=Preroll:integer;"
,
&
buf
))
{
desc
->
preroll
=
atoi
(
buf
);
handled
=
1
;
*
data
=
nl
(
*
data
);
}
if
(
filter
(
*
data
,
"a=length:npt="
,
&
buf
))
{
desc
->
duration
=
(
uint32_t
)(
atof
(
buf
)
*
1000
);
handled
=
1
;
*
data
=
nl
(
*
data
);
}
if
(
filter
(
*
data
,
"a=StreamName:string;"
,
&
buf
))
{
desc
->
stream_name
=
strdup
(
buf
);
desc
->
stream_name_size
=
strlen
(
desc
->
stream_name
);
handled
=
1
;
*
data
=
nl
(
*
data
);
}
if
(
filter
(
*
data
,
"a=mimetype:string;"
,
&
buf
))
{
desc
->
mime_type
=
strdup
(
buf
);
desc
->
mime_type_size
=
strlen
(
desc
->
mime_type
);
handled
=
1
;
*
data
=
nl
(
*
data
);
}
if
(
filter
(
*
data
,
"a=OpaqueData:buffer;"
,
&
buf
))
{
decoded
=
b64_decode
(
buf
,
decoded
,
&
(
desc
->
mlti_data_size
));
desc
->
mlti_data
=
malloc
(
sizeof
(
char
)
*
desc
->
mlti_data_size
);
memcpy
(
desc
->
mlti_data
,
decoded
,
desc
->
mlti_data_size
);
handled
=
1
;
*
data
=
nl
(
*
data
);
lprintf
(
"mlti_data_size: %i
\n
"
,
desc
->
mlti_data_size
);
}
if
(
filter
(
*
data
,
"a=ASMRuleBook:string;"
,
&
buf
))
{
desc
->
asm_rule_book
=
strdup
(
buf
);
handled
=
1
;
*
data
=
nl
(
*
data
);
}
if
(
!
handled
)
{
#ifdef LOG
int
len
=
strchr
(
*
data
,
'\n'
)
-
(
*
data
);
memcpy
(
buf
,
*
data
,
len
+
1
);
buf
[
len
]
=
0
;
printf
(
"libreal: sdpplin: not handled: '%s'
\n
"
,
buf
);
int
len
=
strchr
(
*
data
,
'\n'
)
-
(
*
data
);
memcpy
(
buf
,
*
data
,
len
+
1
);
buf
[
len
]
=
0
;
printf
(
"libreal: sdpplin: not handled: '%s'
\n
"
,
buf
);
#endif
*
data
=
nl
(
*
data
);
*
data
=
nl
(
*
data
);
}
}
}
free
(
buf
);
free
(
decoded
);
return
desc
;
if
(
buf
)
free
(
buf
);
if
(
decoded
)
free
(
decoded
);
return
desc
;
}
sdpplin_t
*
sdpplin_parse
(
char
*
data
)
{
sdpplin_t
*
desc
=
malloc
(
sizeof
(
sdpplin_t
));
sdpplin_stream_t
*
stream
;
char
*
buf
=
malloc
(
3200
);
char
*
decoded
=
malloc
(
3200
);
int
handled
;
int
len
;
memset
(
desc
,
0
,
sizeof
(
sdpplin_t
));
while
(
data
&&
*
data
)
{
handled
=
0
;
if
(
filter
(
data
,
"m="
,
&
buf
))
{
stream
=
sdpplin_parse_stream
(
&
data
);
lprintf
(
"got data for stream id %u
\n
"
,
stream
->
stream_id
);
desc
->
stream
[
stream
->
stream_id
]
=
stream
;
continue
;
}
if
(
filter
(
data
,
"a=Title:buffer;"
,
&
buf
))
{
decoded
=
b64_decode
(
buf
,
decoded
,
&
len
);
desc
->
title
=
strdup
(
decoded
);
handled
=
1
;
data
=
nl
(
data
);
}
if
(
filter
(
data
,
"a=Author:buffer;"
,
&
buf
))
{
decoded
=
b64_decode
(
buf
,
decoded
,
&
len
);
desc
->
author
=
strdup
(
decoded
);
handled
=
1
;
data
=
nl
(
data
);
}
if
(
filter
(
data
,
"a=Copyright:buffer;"
,
&
buf
))
{
decoded
=
b64_decode
(
buf
,
decoded
,
&
len
);
desc
->
copyright
=
strdup
(
decoded
);
handled
=
1
;
data
=
nl
(
data
);
}
if
(
filter
(
data
,
"a=Abstract:buffer;"
,
&
buf
))
{
decoded
=
b64_decode
(
buf
,
decoded
,
&
len
);
desc
->
abstract
=
strdup
(
decoded
);
handled
=
1
;
data
=
nl
(
data
);
}
if
(
filter
(
data
,
"a=StreamCount:integer;"
,
&
buf
))
{
desc
->
stream_count
=
atoi
(
buf
);
desc
->
stream
=
malloc
(
sizeof
(
sdpplin_stream_t
*
)
*
desc
->
stream_count
);
handled
=
1
;
data
=
nl
(
data
);
sdpplin_t
*
sdpplin_parse
(
char
*
data
)
{
sdpplin_t
*
desc
=
malloc
(
sizeof
(
sdpplin_t
));
sdpplin_stream_t
*
stream
;
char
*
buf
=
malloc
(
3200
);
char
*
decoded
=
malloc
(
3200
);
int
handled
;
int
len
;
if
(
!
desc
)
return
NULL
;
if
(
!
buf
)
{
free
(
desc
);
return
NULL
;
}
if
(
filter
(
data
,
"a=Flags:integer;"
,
&
buf
))
{
desc
->
flags
=
atoi
(
buf
);
handled
=
1
;
data
=
nl
(
data
)
;
if
(
!
decoded
)
{
free
(
buf
);
free
(
desc
)
;
return
NULL
;
}
if
(
!
handled
)
{
memset
(
desc
,
0
,
sizeof
(
sdpplin_t
));
while
(
data
&&
*
data
)
{
handled
=
0
;
if
(
filter
(
data
,
"m="
,
&
buf
))
{
stream
=
sdpplin_parse_stream
(
&
data
);
lprintf
(
"got data for stream id %u
\n
"
,
stream
->
stream_id
);
desc
->
stream
[
stream
->
stream_id
]
=
stream
;
continue
;
}
if
(
filter
(
data
,
"a=Title:buffer;"
,
&
buf
))
{
decoded
=
b64_decode
(
buf
,
decoded
,
&
len
);
desc
->
title
=
strdup
(
decoded
);
handled
=
1
;
data
=
nl
(
data
);
}
if
(
filter
(
data
,
"a=Author:buffer;"
,
&
buf
))
{
decoded
=
b64_decode
(
buf
,
decoded
,
&
len
);
desc
->
author
=
strdup
(
decoded
);
handled
=
1
;
data
=
nl
(
data
);
}
if
(
filter
(
data
,
"a=Copyright:buffer;"
,
&
buf
))
{
decoded
=
b64_decode
(
buf
,
decoded
,
&
len
);
desc
->
copyright
=
strdup
(
decoded
);
handled
=
1
;
data
=
nl
(
data
);
}
if
(
filter
(
data
,
"a=Abstract:buffer;"
,
&
buf
))
{
decoded
=
b64_decode
(
buf
,
decoded
,
&
len
);
desc
->
abstract
=
strdup
(
decoded
);
handled
=
1
;
data
=
nl
(
data
);
}
if
(
filter
(
data
,
"a=StreamCount:integer;"
,
&
buf
))
{
desc
->
stream_count
=
atoi
(
buf
);
desc
->
stream
=
malloc
(
sizeof
(
sdpplin_stream_t
*
)
*
desc
->
stream_count
);
handled
=
1
;
data
=
nl
(
data
);
}
if
(
filter
(
data
,
"a=Flags:integer;"
,
&
buf
))
{
desc
->
flags
=
atoi
(
buf
);
handled
=
1
;
data
=
nl
(
data
);
}
if
(
!
handled
)
{
#ifdef LOG
int
len
=
strchr
(
data
,
'\n'
)
-
data
;
memcpy
(
buf
,
data
,
len
+
1
);
buf
[
len
]
=
0
;
printf
(
"libreal: sdpplin: not handled: '%s'
\n
"
,
buf
);
int
len
=
strchr
(
data
,
'\n'
)
-
data
;
memcpy
(
buf
,
data
,
len
+
1
);
buf
[
len
]
=
0
;
printf
(
"libreal: sdpplin: not handled: '%s'
\n
"
,
buf
);
#endif
data
=
nl
(
data
);
data
=
nl
(
data
);
}
}
}
free
(
buf
);
free
(
decoded
);
return
desc
;
free
(
decoded
);
free
(
buf
);
return
desc
;
}
void
sdpplin_free
(
sdpplin_t
*
description
)
{
void
sdpplin_free
(
sdpplin_t
*
description
)
{
/* TODO: free strings */
free
(
description
);
}
modules/access/rtsp/rtsp.c
View file @
66f1e9dd
...
...
@@ -103,7 +103,7 @@ static char *rtsp_get( rtsp_client_t *rtsp )
/*
* rtsp_put puts a line on stream
*/
static
int
rtsp_put
(
rtsp_client_t
*
rtsp
,
const
char
*
psz_string
)
{
int
i_buffer
=
strlen
(
psz_string
);
...
...
@@ -128,7 +128,7 @@ static int rtsp_get_status_code( rtsp_client_t *rtsp, const char *psz_string )
{
char
psz_buffer
[
4
];
int
i_code
=
0
;
if
(
!
strncmp
(
psz_string
,
"RTSP/1.0"
,
sizeof
(
"RTSP/1.0"
)
-
1
)
)
{
memcpy
(
psz_buffer
,
psz_string
+
sizeof
(
"RTSP/1.0"
),
3
);
...
...
@@ -202,7 +202,7 @@ static void rtsp_schedule_standard( rtsp_client_t *rtsp )
/*
* get the answers, if server responses with something != 200, return NULL
*/
static
int
rtsp_get_answers
(
rtsp_client_t
*
rtsp
)
{
char
*
answer
=
NULL
;
...
...
@@ -210,7 +210,7 @@ static int rtsp_get_answers( rtsp_client_t *rtsp )
char
**
answer_ptr
=
rtsp
->
p_private
->
answers
;
int
code
;
int
ans_count
=
0
;
answer
=
rtsp_get
(
rtsp
);
if
(
!
answer
)
return
0
;
code
=
rtsp_get_status_code
(
rtsp
,
answer
);
...
...
@@ -222,7 +222,7 @@ static int rtsp_get_answers( rtsp_client_t *rtsp )
answer
=
rtsp_get
(
rtsp
);
if
(
!
answer
)
return
0
;
if
(
!
strncasecmp
(
answer
,
"Cseq:"
,
5
)
)
{
sscanf
(
answer
,
"%*s %u"
,
&
answer_seq
);
...
...
@@ -283,7 +283,7 @@ static int rtsp_get_answers( rtsp_client_t *rtsp )
int
rtsp_send_ok
(
rtsp_client_t
*
rtsp
)
{
char
cseq
[
16
];
rtsp_put
(
rtsp
,
"RTSP/1.0 200 OK"
);
sprintf
(
cseq
,
"CSeq: %u"
,
rtsp
->
p_private
->
cseq
);
rtsp_put
(
rtsp
,
cseq
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment