Project

General

Profile

Htsp » History » Version 22

Andreas Smas, 2009-02-28 18:24

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