forked from philippe44/LMS-Cast
-
Notifications
You must be signed in to change notification settings - Fork 0
/
how does it work.txt
117 lines (100 loc) · 5.24 KB
/
how does it work.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
problem statement
The STMs shall onyl be sent when a track actually started
======
case 1:
nothing playing,
render.state is stopped,
track_start is NULL
track_started is false
output.state is output_waiting
LMS sends a strms
A waiting socket is created and the output thread is started with an output.state
of stopped. It just waits for the connection
LMS streaming begins and so does the decoding which immediately sets track_start.
The player is given the URI to query and so, asynchronously, a GET will happen,
but it will not start unless some data are in the outputbuf.
The output.state moves to running only upon reception of strmu or on
streaming.state streaming if autostart. The output thread also set the track_started
to true and track_start to NULL as soon as it has sent the 1st byte
Note that the output.state could move to running immediately that would not cause
a problem as, as logn as the player does not GET its data and the decode has not
put anything in the buffer, nothing wrong can happen (maybe the deocder is not running?)
At some point, the player state moves to play, render.state moves to playing and
then because track_started if true, a STRMs is sent, so LMS is all fine
======
case 2:
a track is playing,
render.state is playing
track_start is NULL
track_started is false
output.state is running
a new track is started, interrupting the existing one
LMS sends a strmq, the decoder is flushed first to make sure it will not add
data to the outputbuf then the output is flushed which means that the output
thread is joined and resources are freed. The outputbuf is emptied, track_started
set to false, track_start to NULL, render.state to acquire if it was not stopped
The player is given a stop request, but at this point, it is still
playing and the change of state will come later, asynchronously
LMS sends immediately a strms with a new URI, and everything happens as in case 1
The output thread does send anything until it has received a GET and data are
in the outputbuf and output.state is running (requires a strmu or the decoder to
has started), at which point if the track_started is set to true and track_start
to NULL.
Because the render.state has been set to acquire, STMs message be sent only when
render.state moves back to playing (re-acquired)
=======
case 3:
a track is playing,
render.state is playing
track_start is NULL
track_started is false
output.state is running
a track will finish and there is no other track
a)First, when the whole track has been sent the output_thread detects an
empty buffer. At this point, the decoder.state might still not be complete
because the streamer might not have closed yet. So the output_thread will
go for another round but at some point, it will detect that the
decoder.state is not running any more so it close the socket and exit
b)In parallel the slimproto detects that decoder.state is stopped and sends an
STMd (NB: that can happen pretty quickly on players with large memory buffers).
c)The order of these 2 events is non deterministic
d)Then, when the player stops, it sets render.state to stopped and so with
output.state running, streaming.state disconnected and output buffer empty
slimproto detects an end of track and sends an STMu
=======
case 4:
a track is playing,
render.state is playing
track_start is NULL
track_started is false
output.state is running
a track will finish and there is another track behind
a)As in case 3a there is concurrence between the output thread that detects
an empty buffer and codec not running and slimproto detecting as well an empty
buffer, a codec complete that does send and STMd
b)If the output thread first sees a decode.state complete, it will exit.
c)If slimproto sees first a codec complete, sets the decode.state to stopped
and sends an STMd, then LMS will answer by another STMs. At any time before
the STMs is received, the output thread can detect stop conditions and self-exit
d)When STMs is received, then the output thread will exit if it has not already
The listening socket is re-used as it already open. The player is sent with the
new URI to collect. A GET can happen at any time, it will only start when the
codec starts to fill the buffer
e)The render.state is acquire as set by the previous track when play was received
but as it takes time for the track change to be detected, the decoder can already
be finished as well as all data being sent, in which case LMS will receive a STMd
before the STMs sends another strms and then receives the first STMS. That confuses
it as it's thinking that the 2nd track has started (happens when repositining or on
short tracks). Solution is to add a sentSTMs flag and only send the STMd after this
flag has been set.
In chunked mode, if the last chunk is not sent, players tend to re-ask the same track
over and over. This can happen as whe STMd is sent, the empty chunk might not have been
sent when STMs arrives and output thread is stopped. To prevent that, add an extra
state output_exit when the thread exits and only send the STMd with that state
the protocolinfo contains the whole list of http*/<mime><DLNA crap>
I can extrat just the mime type and then add later the DLNA crap or
ProtocolInfo has 4 fields
- mime type
- DLNA.ORG_PN=MPEG_PS_NTSC
- DLNA.ORG_OP=01
- DLNA.ORG_FLAGS=05100000000000000000000000000000