|
@@ -186,3 +186,112 @@ int ts_nit_add_service_list_descriptor(struct ts_nit *nit, uint16_t ts_id, uint1
|
186
|
186
|
}
|
187
|
187
|
return ts_nit_add_stream(nit, ts_id, org_net_id, desc, desc_size);
|
188
|
188
|
}
|
|
189
|
+
|
|
190
|
+int ts_nit_add_nordig_specifier_descriptor(struct ts_nit *nit, uint16_t ts_id, uint16_t org_net_id) {
|
|
191
|
+ int desc_size = 2 + 4; // 2 for header desc header, 3 for each service
|
|
192
|
+ uint8_t *desc = calloc(1, desc_size);
|
|
193
|
+ int dpos = 0;
|
|
194
|
+ desc[dpos + 0] = 0x5f; // service_list_descriptor
|
|
195
|
+ desc[dpos + 1] = desc_size - 2; // -2 Because of two byte header
|
|
196
|
+ desc[dpos + 2] = 0x00; // -2 Because of two byte header
|
|
197
|
+ desc[dpos + 3] = 0x00; // -2 Because of two byte header
|
|
198
|
+ desc[dpos + 4] = 0x00; // -2 Because of two byte header
|
|
199
|
+ desc[dpos + 5] = 0x29; // -2 Because of two byte header
|
|
200
|
+ dpos += 6;
|
|
201
|
+
|
|
202
|
+ return ts_nit_add_stream(nit, ts_id, org_net_id, desc, desc_size);
|
|
203
|
+}
|
|
204
|
+
|
|
205
|
+int ts_nit_add_lcn_descriptor(struct ts_nit *nit, uint16_t ts_id, uint16_t org_net_id, uint32_t *services, uint8_t num_services) {
|
|
206
|
+ uint8_t i;
|
|
207
|
+ if (!num_services || num_services > 85) // 85 * 3 == 255
|
|
208
|
+ return 0;
|
|
209
|
+ int desc_size = 2 + num_services * 4; // 2 for header desc header, 4 for each service
|
|
210
|
+ uint8_t *desc = calloc(1, desc_size);
|
|
211
|
+ int dpos = 0;
|
|
212
|
+ desc[dpos + 0] = 0x83; // service_lcn_descriptor
|
|
213
|
+ desc[dpos + 1] = desc_size - 2; // -2 Because of two byte header
|
|
214
|
+ dpos += 2;
|
|
215
|
+ for(i=0;i<num_services;i++) {
|
|
216
|
+ uint32_t srv = services[i];
|
|
217
|
+ desc[dpos + 0] = (srv &~ 0x00ffffff) >> 24; // service_id (16 bits)
|
|
218
|
+ desc[dpos + 1] = (srv &~ 0xff00ffff) >> 16; // service_id
|
|
219
|
+ desc[dpos + 2] = (srv &~ 0xffff00ff) >> 8; // visible (1 bit), private (1 bit), first (6 bits) from lcn_number
|
|
220
|
+ desc[dpos + 3] = (srv &~ 0xffffff00); // second (8 bits) lcn_number
|
|
221
|
+ dpos += 4;
|
|
222
|
+ }
|
|
223
|
+ return ts_nit_add_stream(nit, ts_id, org_net_id, desc, desc_size);
|
|
224
|
+}
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+int ts_nit_add_stream_descriptors(struct ts_nit *nit, uint16_t ts_id, uint16_t org_net_id, uint32_t freq, uint8_t modulation, uint32_t symbol_rate, uint32_t *lcn_services, uint32_t *svc_services, uint8_t num_services) {
|
|
228
|
+
|
|
229
|
+ int desc_size = 13 + 6 + 2 + 2 + num_services * 4 + num_services * 3; // 2 for header desc header, + ....
|
|
230
|
+
|
|
231
|
+ uint8_t *desc = calloc(1, desc_size);
|
|
232
|
+
|
|
233
|
+ desc[ 0] = 0x44; // cable_delivey_system_descriptor
|
|
234
|
+ desc[ 1] = 11; // -2 Because of two byte header
|
|
235
|
+ desc[ 2] = ((freq &~ 0x00ffffff) >> 24); // 32 bits, frequency
|
|
236
|
+ desc[ 3] = ((freq &~ 0xff00ffff) >> 16);
|
|
237
|
+ desc[ 4] = ((freq &~ 0xffff00ff) >> 8);
|
|
238
|
+ desc[ 5] = (freq &~ 0xffffff00);
|
|
239
|
+ desc[ 6] = 0xff; // 8 bits reserved
|
|
240
|
+ desc[ 7] = 0xf0; // 4 bits reserved, 4 bits FEC_outer (0 == not defined)
|
|
241
|
+ desc[ 8] = modulation; // 8 bits reserved
|
|
242
|
+ desc[ 9] = (symbol_rate >> 20) &~ 0xffffff00; // 28 bits, symbol_rate
|
|
243
|
+ desc[10] = (symbol_rate >> 12) &~ 0xffffff00;
|
|
244
|
+ desc[11] = (symbol_rate >> 4 ) &~ 0xffffff00;
|
|
245
|
+ desc[12] = (symbol_rate &~ 0xfffffff0) << 4; // 4 bits
|
|
246
|
+ desc[12] |= 0; // 4 bits FEC_inner (0 == not defined)
|
|
247
|
+
|
|
248
|
+ uint8_t i;
|
|
249
|
+ if (!num_services || num_services > 85) // 85 * 3 == 255
|
|
250
|
+ return 0;
|
|
251
|
+
|
|
252
|
+ int desc_svc_size = 2 + num_services * 3; // 2 for header desc header, 3 for each service
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+ int dpos = 13;
|
|
256
|
+
|
|
257
|
+ desc[dpos + 0] = 0x41; // service_list_descriptor
|
|
258
|
+ desc[dpos + 1] = desc_svc_size - 2; // -2 Because of two byte header
|
|
259
|
+ dpos += 2;
|
|
260
|
+ for(i=0;i<num_services;i++) {
|
|
261
|
+ uint32_t srv = svc_services[i];
|
|
262
|
+ desc[dpos + 0] = (srv &~ 0xff00ffff) >> 16; // service_id (16 bits)
|
|
263
|
+ desc[dpos + 1] = (srv &~ 0xffff00ff) >> 8;
|
|
264
|
+ desc[dpos + 2] = (srv &~ 0xffffff00); // service_type (8 bits)
|
|
265
|
+ dpos += 3;
|
|
266
|
+ }
|
|
267
|
+
|
|
268
|
+ int desc_prv_size = 2 + 4; // 2 for header desc header, 3 for each service
|
|
269
|
+
|
|
270
|
+ desc[dpos + 0] = 0x5f; // service_list_descriptor
|
|
271
|
+ desc[dpos + 1] = desc_prv_size - 2; // -2 Because of two byte header
|
|
272
|
+ desc[dpos + 2] = 0x00; // -2 Because of two byte header
|
|
273
|
+ desc[dpos + 3] = 0x00; // -2 Because of two byte header
|
|
274
|
+ desc[dpos + 4] = 0x00; // -2 Because of two byte header
|
|
275
|
+ desc[dpos + 5] = 0x29; // -2 Because of two byte header
|
|
276
|
+ dpos += 6;
|
|
277
|
+
|
|
278
|
+ if (!num_services || num_services > 85) // 85 * 3 == 255
|
|
279
|
+ return 0;
|
|
280
|
+ int desc_lcn_size = 2 + num_services * 4; // 2 for header desc header, 4 for each service
|
|
281
|
+
|
|
282
|
+ desc[dpos + 0] = 0x83; // service_lcn_descriptor
|
|
283
|
+ desc[dpos + 1] = desc_lcn_size - 2; // -2 Because of two byte header
|
|
284
|
+ dpos += 2;
|
|
285
|
+ for(i=0;i<(num_services);i++) {
|
|
286
|
+ uint32_t srv = lcn_services[i];
|
|
287
|
+ desc[dpos + 0] = (srv &~ 0x00ffffff) >> 24; // service_id (16 bits)
|
|
288
|
+ desc[dpos + 1] = (srv &~ 0xff00ffff) >> 16; // service_id
|
|
289
|
+ desc[dpos + 2] = (srv &~ 0xffff00ff) >> 8; // visible (1 bit), private (1 bit), first (6 bits) from lcn_number
|
|
290
|
+ desc[dpos + 3] = (srv &~ 0xffffff00); // second (8 bits) lcn_number
|
|
291
|
+ dpos += 4;
|
|
292
|
+ }
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+ return ts_nit_add_stream(nit, ts_id, org_net_id, desc, desc_size);
|
|
296
|
+}
|
|
297
|
+
|