Project

General

Profile

Htsp » History » Version 19

Andreas Smas, 2009-02-28 18:21

1 17 Andreas Smas
= Home Tv Streaming Protocol (HTSP) =
2 1 Andreas Smas
3 17 Andreas Smas
== General ==
4 1 Andreas Smas
5 17 Andreas Smas
HTSP is a TCP based protocol primarily intended for streaming of live TV and related meta data such as channels, group of channels (called tags in HTSP) and electronic program guide (EPG) information.
6 1 Andreas Smas
7 17 Andreas Smas
The transmission and reception of a channel over HTSP is referred to a subscription. A single HTSP session can handle as many concurrent subscriptions as the bandwidth and CPU permits.
8 1 Andreas Smas
9
10 17 Andreas Smas
The HTSP server in tvheadend has a payload-aware scheduler for prioritizing more important packets (such as I-frames) before less important ones (such as B-frames). This makes HTSP is suitable for long-distance transmissions and/or paths with non-perfect delivery.
11
(It has been tested with a server in Stockholm and the client in Berlin).
12
13 18 Andreas Smas
----
14 17 Andreas Smas
== Communication ==
15
16
There are two distinct ways for communication within HTSP.
17
18
=== RPC communication ===
19 1 Andreas Smas
20 18 Andreas Smas
There is a normal RPC way of doing things. I.e. the client sends a request and the server responds with a reply. All the RPC methods are listed below as the 'Client to Server' methods. Apart from all message fields listed within each message type the client can add an additional field:
21
22
RPC request extra fields:
23 17 Andreas Smas
{{{
24
seq              int  optional   Sequence number. This field will be echoed back by the server in the reply.
25 1 Andreas Smas
}}}
26
This field should be used by the client to match the reply with the request.
27 18 Andreas Smas
All replies are guaranteed to arrive in the same order as the requests.
28
Even so, probably the best way to implement the request-reply client is by taking advantage of the 'seq' field.
29 1 Andreas Smas
30 18 Andreas Smas
RPC reply extra fields:
31
{{{
32
seq              int  optional   Sequence number. Same as in the request.
33
error            str  optional   If present an error has occurred and the text describes the error.
34 19 Andreas Smas
noaccess         int  optional   If present and set to '1' the user is prohibited from invoking the method due to 
35
                                 access restrictions. 
36 18 Andreas Smas
                                 The client should first try to authenticate and then try to re-invoke the method.
37 19 Andreas Smas
challenge        bin  optional   If 'noaccess' is set the server also provides a challenge to be used in the, if
38
                                 the user decides so, upcoming 'authentication' request.
39 18 Andreas Smas
}}}
40 1 Andreas Smas
41
42
43 17 Andreas Smas
=== Streaming communication ===
44 18 Andreas Smas
45 19 Andreas Smas
For streaming of live TV and various related messages the server will continuously push data to the client.
46
These messages are referred to as asynchronous messages and always have the 'method' field set and never have the 'seq' field set.
47
Also, the client can enable an additional asyncMetadata mode and by doing so it will be notified by the server when meta data changes. (EPG updates, creation of channels and tags, etc). 
48 1 Andreas Smas
49
50 19 Andreas Smas
=== Authentication ===
51
52
If the client receives a reply with the 'noaccess' field set it means that it is not allowed to invoke the method.
53
The client can try to 'up' it's access by invoking the 'authenticate' method and then try to re-invoke the original method.
54
55
A typical client would do something like this:
56
{{{
57
 sendRequest() {
58
    
59
 while(1) {
60
  reply = send(request)
61
62
  if(reply.noaccess == 0) {
63
   return reply}
64
  else {
65
66
    do {
67
      ask-user-for-credentials-and-or-get-them-from-keychain
68
       
69
      request.username = name of user
70
      request.digest = sha1(password + reply.challenge)
71
      reply = send(request);
72
    } while(reply.noaccess == 1)
73
  }
74
}}}
75
76
The challenge will always 
77 17 Andreas Smas
78 18 Andreas Smas
----
79 17 Andreas Smas
== Flow of a subscription ==
80
81
When the client wish to receive a channel it starts by sending a 'subscribe' request. The server responds
82
83
84
85 1 Andreas Smas
----
86
87 17 Andreas Smas
= Client to Server (RPC) methods =
88 1 Andreas Smas
89 5 Andreas Smas
----
90 1 Andreas Smas
=== getChallenge ===
91
92 7 Andreas Smas
Request a 32 byte challenge used to generate a authentication digest.
93
94
Request message fields:
95
{{{
96
None
97
}}}
98
99
Reply message fields:
100
{{{
101 9 Andreas Smas
challenge        bin  required   32 bytes of random challenge to be used in next authentication request from client.
102 7 Andreas Smas
}}}
103
104
105 5 Andreas Smas
----
106 1 Andreas Smas
=== authenticate ===
107 8 Andreas Smas
108
Request message fields:
109 7 Andreas Smas
{{{
110
username         str  required   Username.
111
digest           bin  required   SHA-1 hash of [password (not including terminating NUL)] + [challenge]
112
}}}
113 1 Andreas Smas
114 9 Andreas Smas
Reply message fields:
115
{{{
116
noaccess         int  optional   Set to '1' if access was denied.
117 1 Andreas Smas
challenge        bin  optional   32 bytes of random challenge to be used in next authentication request from client.
118 7 Andreas Smas
                                 Always present if 'noaccess' is set. This is supplied so the client does not have
119
                                 to issue an extra 'getChallenge' request.
120
}}}
121 5 Andreas Smas
122 10 Andreas Smas
123
----
124 18 Andreas Smas
=== enableAsyncMetadata ===
125 10 Andreas Smas
126 18 Andreas Smas
When this is enabled the client will get continuous updates from the server about channels and tags.
127 10 Andreas Smas
This also includes creation and deletion of channels and tags. 
128
129
An interactive application that presents the user with information about channels and tags would probably want to switch to this mode.
130
131
132
Request message fields:
133
{{{
134
None
135
}}}
136
137
Reply message fields:
138
{{{
139
None
140
}}}
141
142 1 Andreas Smas
143 5 Andreas Smas
144 1 Andreas Smas
----
145 6 Andreas Smas
=== getEvent ===
146
147 1 Andreas Smas
----
148 6 Andreas Smas
=== subscribe ===
149
150
Request subscription to the given channel. A request for a subscription is always successful.
151 4 Andreas Smas
When the server is ready to transmit data it will first send a 'subscriptionStart' message.
152
153 1 Andreas Smas
154
155
Request message fields:
156 8 Andreas Smas
{{{
157
channelId        int  required   ID for channel. 
158
subscriptionId   int  required   Subscription ID. Selected by client. This value is not interpreted by the server in any form. 
159 1 Andreas Smas
                                 The value is used from now on in all messages related to the subscription.
160 6 Andreas Smas
}}}
161
162
Reply message fields:
163
{{{
164 4 Andreas Smas
None.
165 6 Andreas Smas
}}}
166 5 Andreas Smas
167 1 Andreas Smas
168 5 Andreas Smas
----
169 1 Andreas Smas
=== unsubscribe ===
170 5 Andreas Smas
171
Stop a subscription.
172 1 Andreas Smas
Attributes
173
{{{
174 6 Andreas Smas
subscriptionId   int  required   Subscription ID.
175
}}}
176
177
Reply message fields:
178 2 Andreas Smas
{{{
179
None.
180
}}}
181
182
183
----
184 12 Andreas Smas
185 2 Andreas Smas
= Server to Client methods =
186 1 Andreas Smas
187 11 Andreas Smas
----
188
=== channelAdd ===
189
190
A new channel has been created on the server.
191
192
Message fields:
193
{{{
194
channelId        int   required   ID of channel.
195 13 Andreas Smas
channelName      str   required   Name of channel.
196 11 Andreas Smas
channelIcon      str   required   URL to an icon representative for the channel.
197
eventId          int   optional   ID of the current (or next to be) event on this channel.
198 12 Andreas Smas
tags             int[] optional   Tags this channel is mapped to.
199 1 Andreas Smas
}}}
200
201 11 Andreas Smas
----
202
=== channelUpdate ===
203 1 Andreas Smas
204 11 Andreas Smas
A channel has been updated on the server. All fields will be sent even if they are not changed. Most clients can process this and the 'channelAdd' message
205
with the very same code.
206
207
Message fields:
208
{{{
209
channelId        int   required   ID of channel.
210
channelName      str   required   Name of channel.
211
channelIcon      str   optioanl   URL to an icon representative for the channel.
212 13 Andreas Smas
eventId          int   optional   ID of the current (or next to be) event on this channel.
213 12 Andreas Smas
tags             int[] required   Tags this channel is mapped to.
214 3 Andreas Smas
}}}
215 1 Andreas Smas
216 11 Andreas Smas
----
217 1 Andreas Smas
=== channelDelete ===
218 11 Andreas Smas
219
A channel has been deleted on the server.
220
221
This message is only sent if session is in asynchronous mode.
222
223
Message fields:
224
{{{
225 12 Andreas Smas
channelId        int   required   ID of channel.
226 11 Andreas Smas
}}}
227 1 Andreas Smas
228 11 Andreas Smas
----
229
=== tagAdd ===
230
231
A new tag has been created on the server.
232 13 Andreas Smas
233 11 Andreas Smas
Message fields:
234
{{{
235
tagId            int   required   ID of tag.
236
tagName          str   required   Name of tag.
237
tagIcon          str   optional   URL to an icon representative for the channel.
238 1 Andreas Smas
channels         int[] required   Channels this tag is mapped to.
239 11 Andreas Smas
}}}
240 1 Andreas Smas
241 11 Andreas Smas
----
242
=== tagUpdate ===
243
244
A tag has been updated on the server.
245 13 Andreas Smas
246 11 Andreas Smas
Message fields:
247
{{{
248
tagId            int   required   ID of tag.
249
tagName          str   required   Name of tag.
250
tagIcon          str   optional   URL to an icon representative for the channel.
251 12 Andreas Smas
channels         int[] required   Channels this tag is mapped to.
252 1 Andreas Smas
}}}
253
254 11 Andreas Smas
----
255
=== tagDelete ===
256
257 1 Andreas Smas
A tag has been deleted from the server.
258 11 Andreas Smas
259
Message fields:
260 1 Andreas Smas
{{{
261 11 Andreas Smas
tagId            str   required   ID of tag.
262
}}}
263 12 Andreas Smas
264 11 Andreas Smas
----
265 2 Andreas Smas
=== subscriptionStart ===
266 14 Andreas Smas
267
Message fields:
268
{{{
269
subscriptionId   int   required   Subscription ID.
270
streams          msg[] required   Array of messages with stream information
271
272
273
'streams' message:
274
275
index            int   required   Index for this stream
276
type             str   required   Type of stream
277
language         str   optional   Language for stream
278
279
280
Stream types:
281
    AC3                           AC3 audio
282
    MPEG2AUDIO                    MPEG2 audio (MP2)
283
    MPEG2VIDEO                    MPEG2 video
284
    H264                          H264 video
285
286
287
}}}
288 12 Andreas Smas
289 2 Andreas Smas
----
290
=== subscriptionStop ===
291 15 Andreas Smas
292
Message fields:
293
{{{
294
subscriptionId   int   required   Subscription ID.
295
reason           str   optional   Reason for subscription stop.
296
}}}
297 12 Andreas Smas
298 2 Andreas Smas
----
299
=== subscriptionStatus ===
300 15 Andreas Smas
301
Message fields:
302
{{{
303
subscriptionId   int   required   Subscription ID.
304
status           str   optional   English clear text of status. Absence of this field means that the status is OK. 
305
}}}
306
307 12 Andreas Smas
308 2 Andreas Smas
----
309 15 Andreas Smas
=== queueStatus ===
310
311
The queueStatus message is sent every second during normal data delivery.
312
313
The transmit scheduler have different drop thresholds for different frame types.
314
If congestion occurs it will favor dropping B-frames before P-frames before I-frames.
315
All audio is recognized as I-frames. 
316
317
Message fields:
318
{{{
319
subscriptionId   int   required   Subscription ID.
320
packets          int   required   Number of data packets in queue.
321
bytes            int   required   Number of bytes in queue.
322
delay            int   required   Estimated delay of queue (in µs)
323
Bdrops           int   required   Number of B-frames dropped
324
Pdrops           int   required   Number of P-frames dropped
325
Idrops           int   required   Number of I-frames dropped
326 16 Andreas Smas
}}}
327
328
----
329
=== muxpkt ===
330
331
Streaming data.
332
333
Message fields:
334
{{{
335
subscriptionId   int   required   Subscription ID.
336
frametype        int   required   Type of frame as ASCII value: 'I', 'P', 'B'
337
stream           int   required   Stream index. Corresponds to the streams reported in the subscriptionStart message.
338
dts              int   required   Decode Time Stamp in µs.
339
pts              int   required   Presentation Time Stamp in µs.
340
duration         int   required   Duration of frame in µs.
341
payload          bin   required   Actual frame data.
342
343 1 Andreas Smas
}}}