Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-2-2
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-2-2
Commits
268ff7ea
Commit
268ff7ea
authored
Sep 25, 2005
by
Jean-Paul Saman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Undo coding style fixes to make syncing with Xine code easier
parent
96537a3c
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
892 additions
and
981 deletions
+892
-981
modules/access/rtsp/real.c
modules/access/rtsp/real.c
+302
-318
modules/access/rtsp/real_rmff.c
modules/access/rtsp/real_rmff.c
+315
-354
modules/access/rtsp/real_sdpplin.c
modules/access/rtsp/real_sdpplin.c
+275
-309
No files found.
modules/access/rtsp/real.c
View file @
268ff7ea
...
...
@@ -92,7 +92,7 @@ static void hash(char *field, char *param)
c
=
((
c
<<
0x11
)
|
(
c
>>
0x0f
))
+
d
;
b
=
((
c
&
d
)
|
(
~
c
&
a
))
+
LE_32
((
param
+
0x3c
))
+
b
+
0x49B40821
;
b
=
((
b
<<
0x16
)
|
(
b
>>
0x0a
))
+
c
;
a
=
((
b
&
d
)
|
(
~
d
&
c
))
+
LE_32
((
param
+
0x04
))
+
a
-
0x09E1DA9E
;
a
=
((
a
<<
0x05
)
|
(
a
>>
0x1b
))
+
b
;
d
=
((
a
&
c
)
|
(
~
c
&
b
))
+
LE_32
((
param
+
0x18
))
+
d
-
0x3FBF4CC0
;
...
...
@@ -247,8 +247,7 @@ static void call_hash (char *key, char *challenge, int len) {
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
;
...
...
@@ -273,9 +272,7 @@ static void calc_response (char *result, char *field)
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
;
...
...
@@ -304,8 +301,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
;
...
...
@@ -366,8 +363,8 @@ 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
;
...
...
@@ -423,343 +420,330 @@ 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
=
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
;
}
rmff_header_t
*
real_parse_sdp
(
char
*
data
,
char
**
stream_rules
,
uint32_t
bandwidth
)
{
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
);
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
(
buf
)
free
(
buf
);
return
header
;
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
;
}
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
;
error:
if
(
desc
)
{
sdpplin_free
(
desc
);
free
(
desc
);
}
if
(
header
)
{
rmff_free_header
(
header
);
free
(
header
);
}
if
(
buf
)
free
(
buf
);
return
NULL
;
if
(
desc
)
{
sdpplin_free
(
desc
);
free
(
desc
);
}
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
;
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
)
{
lprintf
(
"got end of stream packet
\n
"
);
return
0
;
}
size
=
(
header
[
1
]
<<
16
)
+
(
header
[
2
]
<<
8
)
+
(
header
[
3
]);
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
];
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
);
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
;
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
;
}
//! 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
=
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
;
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
;
}
/* 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"
));
/* 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
)
);
goto
error
;
}
if
(
size
>
MAX_DESC_BUF
)
{
printf
(
"real: Content-length for description too big (> %uMB)!
\n
"
,
MAX_DESC_BUF
/
(
1024
*
1024
)
);
goto
error
;
}
if
(
!
rtsp_search_answers
(
rtsp_session
,
"ETag"
))
lprintf
(
"real: got no ETag!
\n
"
);
else
session_id
=
strdup
(
rtsp_search_answers
(
rtsp_session
,
"ETag"
));
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
);
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=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"
);
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
);
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
);
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
;
/* 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
;
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 @
268ff7ea
...
...
@@ -183,25 +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
)
{
...
...
@@ -247,379 +247,340 @@ 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
));
if
(
!
fileheader
)
return
NULL
;
rmff_fileheader_t
*
rmff_new_fileheader
(
uint32_t
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
;
rmff_fileheader_t
*
fileheader
=
malloc
(
sizeof
(
rmff_fileheader_t
));
if
(
!
fileheader
)
return
NULL
;
return
fileheader
;
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
;
}
rmff_prop_t
*
rmff_new_prop
(
uint32_t
max_bit_rate
,
uint32_t
avg_bit_rate
,
uint32_t
max_packet_size
,
uint32_t
avg_packet_size
,
uint32_t
num_packets
,
uint32_t
duration
,
uint32_t
preroll
,
uint32_t
index_offset
,
uint32_t
data_offset
,
uint16_t
num_streams
,
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
=
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
;
uint32_t
max_bit_rate
,
uint32_t
avg_bit_rate
,
uint32_t
max_packet_size
,
uint32_t
avg_packet_size
,
uint32_t
num_packets
,
uint32_t
duration
,
uint32_t
preroll
,
uint32_t
index_offset
,
uint32_t
data_offset
,
uint16_t
num_streams
,
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
=
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
;
}
rmff_mdpr_t
*
rmff_new_mdpr
(
uint16_t
stream_number
,
uint32_t
max_bit_rate
,
uint32_t
avg_bit_rate
,
uint32_t
max_packet_size
,
uint32_t
avg_packet_size
,
uint32_t
start_time
,
uint32_t
preroll
,
uint32_t
duration
,
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
));
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
;
uint16_t
stream_number
,
uint32_t
max_bit_rate
,
uint32_t
avg_bit_rate
,
uint32_t
max_packet_size
,
uint32_t
avg_packet_size
,
uint32_t
start_time
,
uint32_t
preroll
,
uint32_t
duration
,
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
));
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
;
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
;
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_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_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
*
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
;
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
;
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
;
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
)
{
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
)
{
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
);
}
}
void
rmff_fix_header
(
rmff_header_t
*
h
)
{
unsigned
int
num_headers
=
0
;
unsigned
int
header_size
=
0
;
rmff_mdpr_t
**
streams
;
int
num_streams
=
0
;
void
rmff_fix_header
(
rmff_header_t
*
h
)
{
if
(
!
h
)
{
lprintf
(
"rmff_fix_header: fatal: no header given.
\n
"
);
return
;
}
if
(
!
h
->
streams
)
{
lprintf
(
"rmff_fix_header: warning: no MDPR chunks
\n
"
);
}
else
{
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
"
);
unsigned
int
num_headers
=
0
;
unsigned
int
header_size
=
0
;
rmff_mdpr_t
**
streams
;
int
num_streams
=
0
;
if
(
h
->
cont
)
{
if
(
!
h
)
{
lprintf
(
"rmff_fix_header: fatal: no header given.
\n
"
);
return
;
}
if
(
!
h
->
streams
)
{
lprintf
(
"rmff_fix_header: warning: no MDPR chunks
\n
"
);
}
else
{
streams
=
h
->
streams
;
while
(
*
streams
)
{
num_streams
++
;
num_headers
++
;
header_size
+=
h
->
cont
->
size
;
header_size
+=
(
*
streams
)
->
size
;
streams
++
;
}
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
));
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
;
}
}
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
"
);
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
;
}
}
header_size
+=
h
->
fileheader
->
size
;
if
(
h
->
cont
)
{
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
));
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
++
;
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
;
}
}
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
->
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
->
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
;
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
;
}
}
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
)
{
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
++
;
}
free
(
h
->
streams
);
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
++
;
}
free
(
h
);
free
(
h
->
streams
);
}
free
(
h
);
}
modules/access/rtsp/real_sdpplin.c
View file @
268ff7ea
...
...
@@ -29,342 +29,308 @@
* Decodes base64 strings (based upon b64 package)
*/
static
char
*
b64_decode
(
const
char
*
in
,
char
*
out
,
int
*
size
)
{
char
dtable
[
256
];
/* Encode / decode table */
int
i
,
k
;
unsigned
int
j
;
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'
);
static
char
*
b64_decode
(
const
char
*
in
,
char
*
out
,
int
*
size
)
{
char
dtable
[
256
];
/* Encode / decode table */
int
i
,
k
;
unsigned
int
j
;
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
];
}
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
;
}
//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
;
}
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
)
{
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
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
;
}
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
;
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
(
!
desc
)
return
NULL
;
memset
(
desc
,
0
,
sizeof
(
sdpplin_stream_t
));
if
(
!
buf
)
goto
error
;
if
(
!
decoded
)
goto
error
;
if
(
!
desc
)
return
NULL
;
memset
(
desc
,
0
,
sizeof
(
sdpplin_stream_t
));
if
(
filter
(
*
data
,
"m="
,
&
buf
))
{
desc
->
id
=
strdup
(
buf
);
}
else
{
lprintf
(
"sdpplin: no m= found.
\n
"
);
goto
error
;
}
*
data
=
nl
(
*
data
);
if
(
!
buf
)
goto
error
;
if
(
!
decoded
)
goto
error
;
while
(
*
data
&&
**
data
&&
*
data
[
0
]
!=
'm'
)
{
handled
=
0
;
if
(
filter
(
*
data
,
"m="
,
&
buf
))
{
desc
->
id
=
strdup
(
buf
);
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
);
}
else
{
lprintf
(
"sdpplin: no m= found.
\n
"
);
goto
error
;
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
);
}
*
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
)
{
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
);
}
if
(
buf
)
free
(
buf
);
if
(
decoded
)
free
(
decoded
);
return
desc
;
}
if
(
buf
)
free
(
buf
);
if
(
decoded
)
free
(
decoded
);
return
desc
;
error:
if
(
decoded
)
free
(
decoded
);
if
(
desc
)
free
(
desc
);
if
(
buf
)
free
(
buf
);
return
NULL
;
if
(
decoded
)
free
(
decoded
);
if
(
desc
)
free
(
desc
);
if
(
buf
)
free
(
buf
);
return
NULL
;
}
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
;
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
(
!
decoded
)
{
free
(
buf
);
free
(
desc
);
return
NULL
;
}
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
(
!
decoded
)
{
free
(
buf
);
free
(
desc
)
;
return
NULL
;
if
(
filter
(
data
,
"a=Title:buffer;"
,
&
buf
))
{
decoded
=
b64_decode
(
buf
,
decoded
,
&
len
);
desc
->
title
=
strdup
(
decoded
);
handled
=
1
;
data
=
nl
(
data
)
;
}
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
)
{
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
(
decoded
);
free
(
buf
);
return
desc
;
free
(
decoded
);
free
(
buf
);
return
desc
;
}
void
sdpplin_free
(
sdpplin_t
*
description
)
{
int
i
;
if
(
!
description
)
return
;
for
(
i
=
0
;
i
<
description
->
stream_count
;
i
++
)
{
if
(
description
->
stream
[
i
]
)
{
if
(
description
->
stream
[
i
]
->
id
)
free
(
description
->
stream
[
i
]
->
id
);
if
(
description
->
stream
[
i
]
->
bandwidth
)
free
(
description
->
stream
[
i
]
->
bandwidth
);
if
(
description
->
stream
[
i
]
->
range
)
free
(
description
->
stream
[
i
]
->
range
);
if
(
description
->
stream
[
i
]
->
length
)
free
(
description
->
stream
[
i
]
->
length
);
if
(
description
->
stream
[
i
]
->
rtpmap
)
free
(
description
->
stream
[
i
]
->
rtpmap
);
if
(
description
->
stream
[
i
]
->
mimetype
)
free
(
description
->
stream
[
i
]
->
mimetype
);
if
(
description
->
stream
[
i
]
->
stream_name
)
free
(
description
->
stream
[
i
]
->
stream_name
);
if
(
description
->
stream
[
i
]
->
mime_type
)
free
(
description
->
stream
[
i
]
->
mime_type
);
if
(
description
->
stream
[
i
]
->
mlti_data
)
free
(
description
->
stream
[
i
]
->
mlti_data
);
if
(
description
->
stream
[
i
]
->
rmff_flags
)
free
(
description
->
stream
[
i
]
->
rmff_flags
);
if
(
description
->
stream
[
i
]
->
asm_rule_book
)
free
(
description
->
stream
[
i
]
->
asm_rule_book
);
}
void
sdpplin_free
(
sdpplin_t
*
description
)
{
int
i
;
if
(
!
description
)
return
;
for
(
i
=
0
;
i
<
description
->
stream_count
;
i
++
)
{
if
(
description
->
stream
[
i
]
)
{
if
(
description
->
stream
[
i
]
->
id
)
free
(
description
->
stream
[
i
]
->
id
);
if
(
description
->
stream
[
i
]
->
bandwidth
)
free
(
description
->
stream
[
i
]
->
bandwidth
);
if
(
description
->
stream
[
i
]
->
range
)
free
(
description
->
stream
[
i
]
->
range
);
if
(
description
->
stream
[
i
]
->
length
)
free
(
description
->
stream
[
i
]
->
length
);
if
(
description
->
stream
[
i
]
->
rtpmap
)
free
(
description
->
stream
[
i
]
->
rtpmap
);
if
(
description
->
stream
[
i
]
->
mimetype
)
free
(
description
->
stream
[
i
]
->
mimetype
);
if
(
description
->
stream
[
i
]
->
stream_name
)
free
(
description
->
stream
[
i
]
->
stream_name
);
if
(
description
->
stream
[
i
]
->
mime_type
)
free
(
description
->
stream
[
i
]
->
mime_type
);
if
(
description
->
stream
[
i
]
->
mlti_data
)
free
(
description
->
stream
[
i
]
->
mlti_data
);
if
(
description
->
stream
[
i
]
->
rmff_flags
)
free
(
description
->
stream
[
i
]
->
rmff_flags
);
if
(
description
->
stream
[
i
]
->
asm_rule_book
)
free
(
description
->
stream
[
i
]
->
asm_rule_book
);
}
free
(
description
->
stream
);
if
(
description
->
owner
)
free
(
description
->
owner
);
if
(
description
->
session_name
)
free
(
description
->
session_name
);
if
(
description
->
session_info
)
free
(
description
->
session_info
);
if
(
description
->
uri
)
free
(
description
->
uri
);
if
(
description
->
email
)
free
(
description
->
email
);
if
(
description
->
phone
)
free
(
description
->
phone
);
if
(
description
->
connection
)
free
(
description
->
connection
);
if
(
description
->
bandwidth
)
free
(
description
->
bandwidth
);
if
(
description
->
title
)
free
(
description
->
title
);
if
(
description
->
author
)
free
(
description
->
author
);
if
(
description
->
copyright
)
free
(
description
->
copyright
);
if
(
description
->
keywords
)
free
(
description
->
keywords
);
if
(
description
->
asm_rule_book
)
free
(
description
->
asm_rule_book
);
if
(
description
->
abstract
)
free
(
description
->
abstract
);
if
(
description
->
range
)
free
(
description
->
range
);
free
(
description
);
}
free
(
description
->
stream
);
if
(
description
->
owner
)
free
(
description
->
owner
);
if
(
description
->
session_name
)
free
(
description
->
session_name
);
if
(
description
->
session_info
)
free
(
description
->
session_info
);
if
(
description
->
uri
)
free
(
description
->
uri
);
if
(
description
->
email
)
free
(
description
->
email
);
if
(
description
->
phone
)
free
(
description
->
phone
);
if
(
description
->
connection
)
free
(
description
->
connection
);
if
(
description
->
bandwidth
)
free
(
description
->
bandwidth
);
if
(
description
->
title
)
free
(
description
->
title
);
if
(
description
->
author
)
free
(
description
->
author
);
if
(
description
->
copyright
)
free
(
description
->
copyright
);
if
(
description
->
keywords
)
free
(
description
->
keywords
);
if
(
description
->
asm_rule_book
)
free
(
description
->
asm_rule_book
);
if
(
description
->
abstract
)
free
(
description
->
abstract
);
if
(
description
->
range
)
free
(
description
->
range
);
free
(
description
);
}
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