Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc
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
Commits
c8d1c51f
Commit
c8d1c51f
authored
Dec 17, 2010
by
Pierre Ynard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
vod: support for adding tracks after start-up
parent
df805945
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
110 additions
and
55 deletions
+110
-55
modules/stream_out/rtp.c
modules/stream_out/rtp.c
+1
-1
modules/stream_out/rtsp.c
modules/stream_out/rtsp.c
+109
-54
No files found.
modules/stream_out/rtp.c
View file @
c8d1c51f
...
@@ -972,7 +972,7 @@ static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
...
@@ -972,7 +972,7 @@ static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
id
->
i_sequence
=
id
->
i_seq_sent_next
;
id
->
i_sequence
=
id
->
i_seq_sent_next
;
}
}
/* vod_init_id() may fail either because the ES wasn't found in
/* vod_init_id() may fail either because the ES wasn't found in
* the VoD media, or because th
at track wasn't SETUP
. In the
* the VoD media, or because th
e RTSP session is gone
. In the
* former case, id->rtp_fmt was left untouched. */
* former case, id->rtp_fmt was left untouched. */
format
=
(
id
->
rtp_fmt
.
ptname
!=
NULL
);
format
=
(
id
->
rtp_fmt
.
ptname
!=
NULL
);
}
}
...
...
modules/stream_out/rtsp.c
View file @
c8d1c51f
...
@@ -443,31 +443,47 @@ int RtspTrackAttach( rtsp_stream_t *rtsp, const char *name,
...
@@ -443,31 +443,47 @@ int RtspTrackAttach( rtsp_stream_t *rtsp, const char *name,
if
(
session
==
NULL
)
if
(
session
==
NULL
)
goto
out
;
goto
out
;
rtsp_strack_t
*
tr
=
NULL
;
for
(
int
i
=
0
;
session
->
trackc
;
i
++
)
for
(
int
i
=
0
;
session
->
trackc
;
i
++
)
{
{
rtsp_strack_t
*
tr
=
session
->
trackv
+
i
;
if
(
session
->
trackv
[
i
].
id
==
id
)
if
(
tr
->
id
==
id
)
{
{
tr
->
rtp_fd
=
dup_socket
(
tr
->
setup_fd
);
tr
=
session
->
trackv
+
i
;
if
(
tr
->
rtp_fd
==
-
1
)
break
;
break
;
}
}
if
(
tr
!=
NULL
)
{
tr
->
sout_id
=
sout_id
;
tr
->
sout_id
=
sout_id
;
tr
->
rtp_fd
=
dup_socket
(
tr
->
setup_fd
);
}
else
{
/* The track was not SETUP. We still create one because we'll
* need the sout_id if we set it up later. */
rtsp_strack_t
track
=
{
.
id
=
id
,
.
sout_id
=
sout_id
,
.
setup_fd
=
-
1
,
.
rtp_fd
=
-
1
};
vlc_rand_bytes
(
&
track
.
seq_init
,
sizeof
(
track
.
seq_init
));
vlc_rand_bytes
(
&
track
.
ssrc
,
sizeof
(
track
.
ssrc
));
INSERT_ELEM
(
session
->
trackv
,
session
->
trackc
,
session
->
trackc
,
track
);
}
uint16_t
seq
;
*
ssrc
=
ntohl
(
tr
->
ssrc
);
*
ssrc
=
ntohl
(
tr
->
ssrc
);
*
seq_init
=
tr
->
seq_init
;
*
seq_init
=
tr
->
seq_init
;
if
(
tr
->
rtp_fd
!=
-
1
)
{
uint16_t
seq
;
rtp_add_sink
(
tr
->
sout_id
,
tr
->
rtp_fd
,
false
,
&
seq
);
rtp_add_sink
(
tr
->
sout_id
,
tr
->
rtp_fd
,
false
,
&
seq
);
/* To avoid race conditions, sout_id->i_seq_sent_next must
/* To avoid race conditions, sout_id->i_seq_sent_next must
* be set here and now. Make sure the caller did its job
* be set here and now. Make sure the caller did its job
* properly when passing seq_init. */
* properly when passing seq_init. */
assert
(
tr
->
seq_init
==
seq
);
assert
(
tr
->
seq_init
==
seq
);
val
=
VLC_SUCCESS
;
break
;
}
}
}
val
=
VLC_SUCCESS
;
out:
out:
vlc_mutex_unlock
(
&
rtsp
->
lock
);
vlc_mutex_unlock
(
&
rtsp
->
lock
);
return
val
;
return
val
;
...
@@ -491,9 +507,21 @@ void RtspTrackDetach( rtsp_stream_t *rtsp, const char *name,
...
@@ -491,9 +507,21 @@ void RtspTrackDetach( rtsp_stream_t *rtsp, const char *name,
rtsp_strack_t
*
tr
=
session
->
trackv
+
i
;
rtsp_strack_t
*
tr
=
session
->
trackv
+
i
;
if
(
tr
->
sout_id
==
sout_id
)
if
(
tr
->
sout_id
==
sout_id
)
{
{
tr
->
sout_id
=
NULL
;
if
(
tr
->
setup_fd
==
-
1
)
rtp_del_sink
(
sout_id
,
tr
->
rtp_fd
);
{
/* No (more) SETUP information: better get rid of the
* track so that we can have new random ssrc and
* seq_init next time. */
REMOVE_ELEM
(
session
->
trackv
,
session
->
trackc
,
i
);
break
;
}
/* We keep the SETUP information of the track, but stop it */
if
(
tr
->
rtp_fd
!=
-
1
)
{
rtp_del_sink
(
tr
->
sout_id
,
tr
->
rtp_fd
);
tr
->
rtp_fd
=
-
1
;
tr
->
rtp_fd
=
-
1
;
}
tr
->
sout_id
=
NULL
;
break
;
break
;
}
}
}
}
...
@@ -506,9 +534,16 @@ out:
...
@@ -506,9 +534,16 @@ out:
/** rtsp must be locked */
/** rtsp must be locked */
static
void
RtspTrackClose
(
rtsp_strack_t
*
tr
)
static
void
RtspTrackClose
(
rtsp_strack_t
*
tr
)
{
{
if
(
tr
->
setup_fd
!=
-
1
)
{
if
(
tr
->
rtp_fd
!=
-
1
)
if
(
tr
->
rtp_fd
!=
-
1
)
{
rtp_del_sink
(
tr
->
sout_id
,
tr
->
rtp_fd
);
rtp_del_sink
(
tr
->
sout_id
,
tr
->
rtp_fd
);
tr
->
rtp_fd
=
-
1
;
}
net_Close
(
tr
->
setup_fd
);
net_Close
(
tr
->
setup_fd
);
tr
->
setup_fd
=
-
1
;
}
}
}
...
@@ -799,18 +834,6 @@ static int RtspHandler( rtsp_stream_t *rtsp, rtsp_stream_id_t *id,
...
@@ -799,18 +834,6 @@ static int RtspHandler( rtsp_stream_t *rtsp, rtsp_stream_id_t *id,
sizeof
(
int
));
sizeof
(
int
));
net_GetSockAddress
(
fd
,
src
,
&
sport
);
net_GetSockAddress
(
fd
,
src
,
&
sport
);
rtsp_strack_t
track
=
{
.
id
=
id
,
.
sout_id
=
id
->
sout_id
,
.
setup_fd
=
fd
,
.
rtp_fd
=
-
1
};
if
(
vod
)
{
vlc_rand_bytes
(
&
track
.
seq_init
,
sizeof
(
track
.
seq_init
));
vlc_rand_bytes
(
&
track
.
ssrc
,
sizeof
(
track
.
ssrc
));
ssrc
=
track
.
ssrc
;
}
else
ssrc
=
id
->
ssrc
;
vlc_mutex_lock
(
&
rtsp
->
lock
);
vlc_mutex_lock
(
&
rtsp
->
lock
);
if
(
psz_session
==
NULL
)
if
(
psz_session
==
NULL
)
{
{
...
@@ -832,28 +855,53 @@ static int RtspHandler( rtsp_stream_t *rtsp, rtsp_stream_id_t *id,
...
@@ -832,28 +855,53 @@ static int RtspHandler( rtsp_stream_t *rtsp, rtsp_stream_id_t *id,
}
}
RtspClientAlive
(
ses
);
RtspClientAlive
(
ses
);
/* Bail if the track is already set up: we don't
rtsp_strack_t
*
tr
=
NULL
;
* support changing the transport parameters on the
* fly */
bool
setup
=
false
;
for
(
int
i
=
0
;
i
<
ses
->
trackc
;
i
++
)
for
(
int
i
=
0
;
i
<
ses
->
trackc
;
i
++
)
{
{
if
(
ses
->
trackv
[
i
].
id
==
id
)
if
(
ses
->
trackv
[
i
].
id
==
id
)
{
{
setup
=
true
;
tr
=
ses
->
trackv
+
i
;
break
;
break
;
}
}
}
}
if
(
setup
)
if
(
tr
==
NULL
)
{
/* Set up a new track */
rtsp_strack_t
track
=
{
.
id
=
id
,
.
sout_id
=
id
->
sout_id
,
.
setup_fd
=
fd
,
.
rtp_fd
=
-
1
};
if
(
vod
)
{
vlc_rand_bytes
(
&
track
.
seq_init
,
sizeof
(
track
.
seq_init
));
vlc_rand_bytes
(
&
track
.
ssrc
,
sizeof
(
track
.
ssrc
));
ssrc
=
track
.
ssrc
;
}
else
ssrc
=
id
->
ssrc
;
INSERT_ELEM
(
ses
->
trackv
,
ses
->
trackc
,
ses
->
trackc
,
track
);
}
else
if
(
tr
->
setup_fd
==
-
1
)
{
/* The track was not SETUP, but it exists
* because there is a sout_id running for it */
tr
->
setup_fd
=
fd
;
}
else
{
{
/* The track is already set up, and we don't
* support changing the transport parameters on
* the fly */
vlc_mutex_unlock
(
&
rtsp
->
lock
);
vlc_mutex_unlock
(
&
rtsp
->
lock
);
answer
->
i_status
=
455
;
answer
->
i_status
=
455
;
net_Close
(
fd
);
net_Close
(
fd
);
break
;
break
;
}
}
INSERT_ELEM
(
ses
->
trackv
,
ses
->
trackc
,
ses
->
trackc
,
track
);
vlc_mutex_unlock
(
&
rtsp
->
lock
);
vlc_mutex_unlock
(
&
rtsp
->
lock
);
httpd_ServerIP
(
cl
,
ip
);
httpd_ServerIP
(
cl
,
ip
);
...
@@ -915,10 +963,7 @@ static int RtspHandler( rtsp_stream_t *rtsp, rtsp_stream_id_t *id,
...
@@ -915,10 +963,7 @@ static int RtspHandler( rtsp_stream_t *rtsp, rtsp_stream_id_t *id,
if
(
vod
)
if
(
vod
)
{
{
/* We don't keep a reference to the sout_stream_t,
/* We don't keep a reference to the sout_stream_t,
* so we check if a sout_id is available instead.
* so we check if a sout_id is available instead. */
* FIXME: this is broken if the stream is still
* running but with no track set up; but this case
* is already broken anyway (see below). */
for
(
int
i
=
0
;
i
<
ses
->
trackc
;
i
++
)
for
(
int
i
=
0
;
i
<
ses
->
trackc
;
i
++
)
{
{
sout_id
=
ses
->
trackv
[
i
].
sout_id
;
sout_id
=
ses
->
trackv
[
i
].
sout_id
;
...
@@ -934,17 +979,20 @@ static int RtspHandler( rtsp_stream_t *rtsp, rtsp_stream_id_t *id,
...
@@ -934,17 +979,20 @@ static int RtspHandler( rtsp_stream_t *rtsp, rtsp_stream_id_t *id,
rtsp_strack_t
*
tr
=
ses
->
trackv
+
i
;
rtsp_strack_t
*
tr
=
ses
->
trackv
+
i
;
if
(
(
id
==
NULL
)
||
(
tr
->
id
==
id
)
)
if
(
(
id
==
NULL
)
||
(
tr
->
id
==
id
)
)
{
{
if
(
tr
->
setup_fd
==
-
1
)
/* Track not SETUP */
continue
;
uint16_t
seq
;
uint16_t
seq
;
if
(
tr
->
rtp_fd
==
-
1
)
if
(
tr
->
rtp_fd
==
-
1
)
{
{
if
(
vod
)
/* Track not PLAYing yet */
/* TODO: if the RTP stream output is already
if
(
tr
->
sout_id
==
NULL
)
* started, it won't pick up newly set-up
/* Instance not running yet (VoD) */
* tracks, so we need to call rtp_add_sink()
* or something. */
seq
=
tr
->
seq_init
;
seq
=
tr
->
seq_init
;
else
else
{
{
/* Instance running, add a sink to it */
tr
->
rtp_fd
=
dup_socket
(
tr
->
setup_fd
);
tr
->
rtp_fd
=
dup_socket
(
tr
->
setup_fd
);
if
(
tr
->
rtp_fd
==
-
1
)
if
(
tr
->
rtp_fd
==
-
1
)
continue
;
continue
;
...
@@ -955,6 +1003,7 @@ static int RtspHandler( rtsp_stream_t *rtsp, rtsp_stream_id_t *id,
...
@@ -955,6 +1003,7 @@ static int RtspHandler( rtsp_stream_t *rtsp, rtsp_stream_id_t *id,
}
}
else
else
{
{
/* Track already playing */
assert
(
tr
->
sout_id
!=
NULL
);
assert
(
tr
->
sout_id
!=
NULL
);
seq
=
rtp_get_seq
(
tr
->
sout_id
);
seq
=
rtp_get_seq
(
tr
->
sout_id
);
}
}
...
@@ -1029,12 +1078,15 @@ static int RtspHandler( rtsp_stream_t *rtsp, rtsp_stream_id_t *id,
...
@@ -1029,12 +1078,15 @@ static int RtspHandler( rtsp_stream_t *rtsp, rtsp_stream_id_t *id,
rtsp_strack_t
*
tr
=
ses
->
trackv
+
i
;;
rtsp_strack_t
*
tr
=
ses
->
trackv
+
i
;;
if
(
tr
->
id
==
id
)
if
(
tr
->
id
==
id
)
{
{
if
(
tr
->
setup_fd
==
-
1
)
break
;
found
=
true
;
if
(
tr
->
rtp_fd
!=
-
1
)
if
(
tr
->
rtp_fd
!=
-
1
)
{
{
rtp_del_sink
(
tr
->
sout_id
,
tr
->
rtp_fd
);
rtp_del_sink
(
tr
->
sout_id
,
tr
->
rtp_fd
);
tr
->
rtp_fd
=
-
1
;
tr
->
rtp_fd
=
-
1
;
}
}
found
=
true
;
break
;
break
;
}
}
}
}
...
@@ -1089,6 +1141,9 @@ static int RtspHandler( rtsp_stream_t *rtsp, rtsp_stream_id_t *id,
...
@@ -1089,6 +1141,9 @@ static int RtspHandler( rtsp_stream_t *rtsp, rtsp_stream_id_t *id,
if
(
ses
->
trackv
[
i
].
id
==
id
)
if
(
ses
->
trackv
[
i
].
id
==
id
)
{
{
RtspTrackClose
(
&
ses
->
trackv
[
i
]
);
RtspTrackClose
(
&
ses
->
trackv
[
i
]
);
/* Keep VoD tracks whose instance is still
* running */
if
(
!
(
vod
&&
ses
->
trackv
[
i
].
sout_id
!=
NULL
))
REMOVE_ELEM
(
ses
->
trackv
,
ses
->
trackc
,
i
);
REMOVE_ELEM
(
ses
->
trackv
,
ses
->
trackc
,
i
);
}
}
}
}
...
...
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