Project

General

Profile

Htsp » History » Version 26

Andreas Smas, 2009-02-28 23:29

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 22 Andreas Smas
An example client can be found [http://trac.lonelycoder.com/hts/browser/trunk/showtime/tv/htsp.c here]
14
15 18 Andreas Smas
----
16 17 Andreas Smas
== Communication ==
17
18 23 Andreas Smas
This communication is currently implemented by using htsmsg:s. All strings are encoded as UTF-8.
19
20 17 Andreas Smas
There are two distinct ways for communication within HTSP.
21
22
=== RPC communication ===
23 1 Andreas Smas
24 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:
25
26
RPC request extra fields:
27 17 Andreas Smas
{{{
28
seq              int  optional   Sequence number. This field will be echoed back by the server in the reply.
29 1 Andreas Smas
}}}
30
This field should be used by the client to match the reply with the request.
31 18 Andreas Smas
All replies are guaranteed to arrive in the same order as the requests.
32
Even so, probably the best way to implement the request-reply client is by taking advantage of the 'seq' field.
33 1 Andreas Smas
34 18 Andreas Smas
RPC reply extra fields:
35
{{{
36
seq              int  optional   Sequence number. Same as in the request.
37
error            str  optional   If present an error has occurred and the text describes the error.
38 19 Andreas Smas
noaccess         int  optional   If present and set to '1' the user is prohibited from invoking the method due to 
39
                                 access restrictions. 
40 18 Andreas Smas
                                 The client should first try to authenticate and then try to re-invoke the method.
41 19 Andreas Smas
challenge        bin  optional   If 'noaccess' is set the server also provides a challenge to be used in the, if
42
                                 the user decides so, upcoming 'authentication' request.
43 18 Andreas Smas
}}}
44 1 Andreas Smas
45
46
47 17 Andreas Smas
=== Streaming communication ===
48 18 Andreas Smas
49 19 Andreas Smas
For streaming of live TV and various related messages the server will continuously push data to the client.
50
These messages are referred to as asynchronous messages and always have the 'method' field set and never have the 'seq' field set.
51
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). 
52 1 Andreas Smas
53
54 19 Andreas Smas
=== Authentication ===
55
56 20 Andreas Smas
If the client receives a reply with the 'noaccess' field set it means that it was not allowed to invoke that method.
57
The client can try to raise it's access by invoking the 'authenticate' method and then try to re-invoke the original method.
58 19 Andreas Smas
59
A typical client would do something like this:
60
{{{
61
 sendRequest() {
62
    
63
 while(1) {
64
  reply = send(request)
65
66
  if(reply.noaccess == 0) {
67
   return reply}
68
  else {
69
70
    do {
71
      ask-user-for-credentials-and-or-get-them-from-keychain
72
       
73 21 Andreas Smas
      authrequest.username = name of user
74
      authrequest.digest = sha1(password + reply.challenge)
75
      reply = send(authrequest);
76 19 Andreas Smas
    } while(reply.noaccess == 1)
77
  }
78
}}}
79
80 20 Andreas Smas
The challenge will always be present when 'noaccess' is set.
81 1 Andreas Smas
82 24 Andreas Smas
It is also possible to have the client authenticate itself without it having to be a direct result of a denied method invocation.
83
This can be done by just asking for a challenge (using the 'getChallenge' request) and then perform an 'authenticate' request.
84
85 1 Andreas Smas
----
86 17 Andreas Smas
= Client to Server (RPC) methods =
87 1 Andreas Smas
88 5 Andreas Smas
----
89 1 Andreas Smas
=== getChallenge ===
90
91 7 Andreas Smas
Request a 32 byte challenge used to generate a authentication digest.
92
93
Request message fields:
94
{{{
95
None
96
}}}
97
98
Reply message fields:
99
{{{
100 9 Andreas Smas
challenge        bin  required   32 bytes of random challenge to be used in next authentication request from client.
101 7 Andreas Smas
}}}
102
103
104 5 Andreas Smas
----
105 1 Andreas Smas
=== authenticate ===
106 8 Andreas Smas
107
Request message fields:
108 7 Andreas Smas
{{{
109
username         str  required   Username.
110
digest           bin  required   SHA-1 hash of [password (not including terminating NUL)] + [challenge]
111
}}}
112 1 Andreas Smas
113 9 Andreas Smas
Reply message fields:
114
{{{
115
noaccess         int  optional   Set to '1' if access was denied.
116 1 Andreas Smas
challenge        bin  optional   32 bytes of random challenge to be used in next authentication request from client.
117 7 Andreas Smas
                                 Always present if 'noaccess' is set. This is supplied so the client does not have
118
                                 to issue an extra 'getChallenge' request.
119
}}}
120 5 Andreas Smas
121 26 Andreas Smas
----
122
=== getInfo ===
123
124
Request information about the server.
125
126
Request message fields:
127
{{{
128
}}}
129
130
Reply message fields:
131
{{{
132
appname          str  required   Server software name.
133
appver           str  required   Server software version.
134
protover         int  required   HTSP version.
135
}}}
136 10 Andreas Smas
137
----
138 18 Andreas Smas
=== enableAsyncMetadata ===
139 10 Andreas Smas
140 18 Andreas Smas
When this is enabled the client will get continuous updates from the server about channels and tags.
141 10 Andreas Smas
This also includes creation and deletion of channels and tags. 
142
143
An interactive application that presents the user with information about channels and tags would probably want to switch to this mode.
144
145
146
Request message fields:
147
{{{
148
None
149
}}}
150
151
Reply message fields:
152
{{{
153
None
154
}}}
155
156 1 Andreas Smas
157 5 Andreas Smas
158 1 Andreas Smas
----
159 6 Andreas Smas
=== getEvent ===
160 23 Andreas Smas
161
Request information about the given event. An event typically corresponds to a program on a channel.
162
163
Request message fields:
164
{{{
165
eventId          int  required   Event ID.
166
}}}
167
168
Reply message fields:
169
{{{
170
start            int  required   Start time of event (Seconds since the epoch, in UTC)
171
stop             int  required   Ending time of event (Seconds since the epoch, in UTC)
172
title            str  required   Title of event.
173
description      str  required   Description of event. This can be quite huge and may also contain newlines.
174
nextEventId      int  optional   ID of next event on the same channel.
175
}}}
176 6 Andreas Smas
177 1 Andreas Smas
----
178 6 Andreas Smas
=== subscribe ===
179
180 25 Andreas Smas
Request subscription to the given channel. 
181 1 Andreas Smas
182
Request message fields:
183 8 Andreas Smas
{{{
184
channelId        int  required   ID for channel. 
185
subscriptionId   int  required   Subscription ID. Selected by client. This value is not interpreted by the server in any form. 
186 1 Andreas Smas
                                 The value is used from now on in all messages related to the subscription.
187 6 Andreas Smas
}}}
188
189
Reply message fields:
190
{{{
191 4 Andreas Smas
None.
192 6 Andreas Smas
}}}
193 5 Andreas Smas
194 1 Andreas Smas
195 5 Andreas Smas
----
196 1 Andreas Smas
=== unsubscribe ===
197 5 Andreas Smas
198
Stop a subscription.
199 1 Andreas Smas
Attributes
200
{{{
201 6 Andreas Smas
subscriptionId   int  required   Subscription ID.
202
}}}
203
204
Reply message fields:
205 2 Andreas Smas
{{{
206
None.
207
}}}
208
209
210
----
211 12 Andreas Smas
212 2 Andreas Smas
= Server to Client methods =
213 1 Andreas Smas
214 11 Andreas Smas
----
215
=== channelAdd ===
216
217
A new channel has been created on the server.
218
219
Message fields:
220
{{{
221
channelId        int   required   ID of channel.
222 13 Andreas Smas
channelName      str   required   Name of channel.
223 11 Andreas Smas
channelIcon      str   required   URL to an icon representative for the channel.
224
eventId          int   optional   ID of the current (or next to be) event on this channel.
225 12 Andreas Smas
tags             int[] optional   Tags this channel is mapped to.
226 1 Andreas Smas
}}}
227
228 11 Andreas Smas
----
229
=== channelUpdate ===
230 1 Andreas Smas
231 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
232
with the very same code.
233
234
Message fields:
235
{{{
236
channelId        int   required   ID of channel.
237
channelName      str   required   Name of channel.
238
channelIcon      str   optioanl   URL to an icon representative for the channel.
239 13 Andreas Smas
eventId          int   optional   ID of the current (or next to be) event on this channel.
240 12 Andreas Smas
tags             int[] required   Tags this channel is mapped to.
241 3 Andreas Smas
}}}
242 1 Andreas Smas
243 11 Andreas Smas
----
244 1 Andreas Smas
=== channelDelete ===
245 11 Andreas Smas
246
A channel has been deleted on the server.
247
248
This message is only sent if session is in asynchronous mode.
249
250
Message fields:
251
{{{
252 12 Andreas Smas
channelId        int   required   ID of channel.
253 11 Andreas Smas
}}}
254 1 Andreas Smas
255 11 Andreas Smas
----
256
=== tagAdd ===
257
258
A new tag has been created on the server.
259 13 Andreas Smas
260 11 Andreas Smas
Message fields:
261
{{{
262
tagId            int   required   ID of tag.
263
tagName          str   required   Name of tag.
264
tagIcon          str   optional   URL to an icon representative for the channel.
265 1 Andreas Smas
channels         int[] required   Channels this tag is mapped to.
266 11 Andreas Smas
}}}
267 1 Andreas Smas
268 11 Andreas Smas
----
269
=== tagUpdate ===
270
271
A tag has been updated on the server.
272 13 Andreas Smas
273 11 Andreas Smas
Message fields:
274
{{{
275
tagId            int   required   ID of tag.
276
tagName          str   required   Name of tag.
277
tagIcon          str   optional   URL to an icon representative for the channel.
278 12 Andreas Smas
channels         int[] required   Channels this tag is mapped to.
279 1 Andreas Smas
}}}
280
281 11 Andreas Smas
----
282
=== tagDelete ===
283
284 1 Andreas Smas
A tag has been deleted from the server.
285 11 Andreas Smas
286
Message fields:
287 1 Andreas Smas
{{{
288 11 Andreas Smas
tagId            str   required   ID of tag.
289
}}}
290 12 Andreas Smas
291 11 Andreas Smas
----
292 2 Andreas Smas
=== subscriptionStart ===
293 14 Andreas Smas
294
Message fields:
295
{{{
296
subscriptionId   int   required   Subscription ID.
297
streams          msg[] required   Array of messages with stream information
298
299
300
'streams' message:
301
302
index            int   required   Index for this stream
303
type             str   required   Type of stream
304
language         str   optional   Language for stream
305
306
307
Stream types:
308
    AC3                           AC3 audio
309
    MPEG2AUDIO                    MPEG2 audio (MP2)
310
    MPEG2VIDEO                    MPEG2 video
311
    H264                          H264 video
312 1 Andreas Smas
313 14 Andreas Smas
314
}}}
315 21 Andreas Smas
316 12 Andreas Smas
317 2 Andreas Smas
----
318
=== subscriptionStop ===
319 15 Andreas Smas
320
Message fields:
321
{{{
322
subscriptionId   int   required   Subscription ID.
323
reason           str   optional   Reason for subscription stop.
324
}}}
325 12 Andreas Smas
326 2 Andreas Smas
----
327
=== subscriptionStatus ===
328 15 Andreas Smas
329
Message fields:
330
{{{
331
subscriptionId   int   required   Subscription ID.
332
status           str   optional   English clear text of status. Absence of this field means that the status is OK. 
333
}}}
334
335 12 Andreas Smas
336 2 Andreas Smas
----
337 15 Andreas Smas
=== queueStatus ===
338
339
The queueStatus message is sent every second during normal data delivery.
340
341
The transmit scheduler have different drop thresholds for different frame types.
342
If congestion occurs it will favor dropping B-frames before P-frames before I-frames.
343
All audio is recognized as I-frames. 
344
345
Message fields:
346
{{{
347
subscriptionId   int   required   Subscription ID.
348
packets          int   required   Number of data packets in queue.
349
bytes            int   required   Number of bytes in queue.
350
delay            int   required   Estimated delay of queue (in µs)
351
Bdrops           int   required   Number of B-frames dropped
352
Pdrops           int   required   Number of P-frames dropped
353
Idrops           int   required   Number of I-frames dropped
354 16 Andreas Smas
}}}
355
356
----
357
=== muxpkt ===
358
359
Streaming data.
360
361
Message fields:
362
{{{
363
subscriptionId   int   required   Subscription ID.
364
frametype        int   required   Type of frame as ASCII value: 'I', 'P', 'B'
365
stream           int   required   Stream index. Corresponds to the streams reported in the subscriptionStart message.
366
dts              int   required   Decode Time Stamp in µs.
367
pts              int   required   Presentation Time Stamp in µs.
368
duration         int   required   Duration of frame in µs.
369
payload          bin   required   Actual frame data.
370
371 1 Andreas Smas
}}}