ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Linux-DVB/DVB.xs
Revision: 1.3
Committed: Sun Apr 3 02:16:05 2005 UTC (19 years, 1 month ago) by root
Branch: MAIN
Changes since 1.2: +83 -8 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 #include "EXTERN.h"
2 #include "perl.h"
3 #include "XSUB.h"
4
5 #include <string.h>
6
7 #include <linux/dvb/frontend.h>
8 #include <linux/dvb/dmx.h>
9
10 #define CONST(name) { #name, name }
11
12 enum {
13 SCT_PAT = 0x00,
14 SCT_CAT = 0x01,
15 SCT_PMT = 0x02,
16 SCT_TSDT = 0x03,
17 SCT_NIT = 0x40,//TODO
18 SCT_NIT_OTHER = 0x41,
19 SCT_SDT = 0x42,
20 SCT_SDT_OTHER = 0x46,
21 SCT_BAT = 0x4a,//TODO
22 SCT_EIT_PRESENT = 0x4e,
23 SCT_EIT_PRESENT_OTHER = 0x4f,
24 SCT_EIT_SCHEDULE0 = 0x50,
25 SCT_EIT_SCHEDULE15 = 0x5f,
26 SCT_EIT_SCHEDULE_OTHER0 = 0x60,
27 SCT_EIT_SCHEDULE_OTHER15 = 0x6f,
28 SCT_TDT = 0x70,
29 SCT_RST = 0x71,
30 SCT_ST = 0x72,
31 SCT_TOT = 0x73,
32 SCT_RNT = 0x74,
33 SCT_CST = 0x75,
34 SCT_RCT = 0x76,
35 SCT_CIT = 0x77,
36 SCT_MPE = 0x78,
37 SCT_DIT = 0x7e,
38 SCT_SIT = 0x7f,
39 };
40
41 enum {
42 DT_service = 0x48,
43 DT_country_availability = 0x49,
44 DT_linkage = 0x4a,
45 DT_short_event = 0x4d,
46 DT_extended_event = 0x4e, //NYI
47 DT_component = 0x50,
48 DT_content = 0x54,
49 DT_private_data_specifier = 0x5f,
50 DT_short_smoothing_buffer = 0x61, //NYI
51 DT_scrambling_indicator = 0x65, //NYI
52 DT_PDC = 0x69,
53 };
54
55 static const struct consts {
56 const char *name;
57 const long value;
58 } consts [] = {
59 CONST (FE_QPSK),
60 CONST (FE_QAM),
61 CONST (FE_OFDM),
62
63 CONST (FE_IS_STUPID),
64 CONST (FE_CAN_INVERSION_AUTO),
65 CONST (FE_CAN_FEC_1_2),
66 CONST (FE_CAN_FEC_2_3),
67 CONST (FE_CAN_FEC_3_4),
68 CONST (FE_CAN_FEC_4_5),
69 CONST (FE_CAN_FEC_5_6),
70 CONST (FE_CAN_FEC_6_7),
71 CONST (FE_CAN_FEC_7_8),
72 CONST (FE_CAN_FEC_8_9),
73 CONST (FE_CAN_FEC_AUTO),
74 CONST (FE_CAN_QPSK),
75 CONST (FE_CAN_QAM_16),
76 CONST (FE_CAN_QAM_32),
77 CONST (FE_CAN_QAM_64),
78 CONST (FE_CAN_QAM_128),
79 CONST (FE_CAN_QAM_256),
80 CONST (FE_CAN_QAM_AUTO),
81 CONST (FE_CAN_TRANSMISSION_MODE_AUTO),
82 CONST (FE_CAN_BANDWIDTH_AUTO),
83 CONST (FE_CAN_GUARD_INTERVAL_AUTO),
84 CONST (FE_CAN_HIERARCHY_AUTO),
85 CONST (FE_NEEDS_BENDING),
86 CONST (FE_CAN_RECOVER),
87 CONST (FE_CAN_MUTE_TS),
88
89 CONST (FE_HAS_SIGNAL),
90 CONST (FE_HAS_CARRIER),
91 CONST (FE_HAS_VITERBI),
92 CONST (FE_HAS_SYNC),
93 CONST (FE_HAS_LOCK),
94 CONST (FE_TIMEDOUT),
95 CONST (FE_REINIT),
96
97 CONST (INVERSION_OFF),
98 CONST (INVERSION_ON),
99 CONST (INVERSION_AUTO),
100
101 CONST (FEC_NONE),
102 CONST (FEC_1_2),
103 CONST (FEC_2_3),
104 CONST (FEC_3_4),
105 CONST (FEC_4_5),
106 CONST (FEC_5_6),
107 CONST (FEC_6_7),
108 CONST (FEC_7_8),
109 CONST (FEC_8_9),
110 CONST (FEC_AUTO),
111
112 CONST (QPSK),
113 CONST (QAM_16),
114 CONST (QAM_32),
115 CONST (QAM_64),
116 CONST (QAM_128),
117 CONST (QAM_256),
118 CONST (QAM_AUTO),
119
120 CONST (TRANSMISSION_MODE_2K),
121 CONST (TRANSMISSION_MODE_8K),
122 CONST (TRANSMISSION_MODE_AUTO),
123
124 CONST (BANDWIDTH_8_MHZ),
125 CONST (BANDWIDTH_7_MHZ),
126 CONST (BANDWIDTH_6_MHZ),
127 CONST (BANDWIDTH_AUTO),
128
129 CONST (GUARD_INTERVAL_1_32),
130 CONST (GUARD_INTERVAL_1_16),
131 CONST (GUARD_INTERVAL_1_8),
132 CONST (GUARD_INTERVAL_1_4),
133 CONST (GUARD_INTERVAL_AUTO),
134
135 CONST (HIERARCHY_NONE),
136 CONST (HIERARCHY_1),
137 CONST (HIERARCHY_2),
138 CONST (HIERARCHY_4),
139 CONST (HIERARCHY_AUTO),
140
141 CONST (DMX_OUT_DECODER),
142 CONST (DMX_OUT_TAP),
143 CONST (DMX_OUT_TS_TAP),
144
145 CONST (DMX_IN_FRONTEND),
146 CONST (DMX_IN_DVR),
147
148 CONST (DMX_PES_AUDIO0),
149 CONST (DMX_PES_VIDEO0),
150 CONST (DMX_PES_TELETEXT0),
151 CONST (DMX_PES_SUBTITLE0),
152 CONST (DMX_PES_PCR0),
153
154 CONST (DMX_PES_AUDIO1),
155 CONST (DMX_PES_VIDEO1),
156 CONST (DMX_PES_TELETEXT1),
157 CONST (DMX_PES_SUBTITLE1),
158 CONST (DMX_PES_PCR1),
159
160 CONST (DMX_PES_AUDIO2),
161 CONST (DMX_PES_VIDEO2),
162 CONST (DMX_PES_TELETEXT2),
163 CONST (DMX_PES_SUBTITLE2),
164 CONST (DMX_PES_PCR2),
165
166 CONST (DMX_PES_AUDIO3),
167 CONST (DMX_PES_VIDEO3),
168 CONST (DMX_PES_TELETEXT3),
169 CONST (DMX_PES_SUBTITLE3),
170 CONST (DMX_PES_PCR3),
171
172 CONST (DMX_PES_OTHER),
173
174 CONST (DMX_PES_AUDIO),
175 CONST (DMX_PES_VIDEO),
176 CONST (DMX_PES_TELETEXT),
177 CONST (DMX_PES_SUBTITLE),
178 CONST (DMX_PES_PCR),
179
180 CONST (DMX_SCRAMBLING_EV),
181 CONST (DMX_FRONTEND_EV),
182
183 CONST (DMX_CHECK_CRC),
184 CONST (DMX_ONESHOT),
185 CONST (DMX_IMMEDIATE_START),
186 CONST (DMX_KERNEL_CLIENT),
187
188 CONST (DMX_SOURCE_FRONT0),
189 CONST (DMX_SOURCE_FRONT1),
190 CONST (DMX_SOURCE_FRONT2),
191 CONST (DMX_SOURCE_FRONT3),
192
193 CONST (DMX_SOURCE_DVR0),
194 CONST (DMX_SOURCE_DVR1),
195 CONST (DMX_SOURCE_DVR2),
196 CONST (DMX_SOURCE_DVR3),
197
198 CONST (DMX_SCRAMBLING_OFF),
199 CONST (DMX_SCRAMBLING_ON),
200
201 // constants defined by this file
202 CONST (SCT_PAT),
203 CONST (SCT_CAT),
204 CONST (SCT_PMT),
205 CONST (SCT_TSDT),
206 CONST (SCT_NIT),
207 CONST (SCT_NIT_OTHER),
208 CONST (SCT_SDT),
209 CONST (SCT_SDT_OTHER),
210 CONST (SCT_BAT),
211 CONST (SCT_EIT_PRESENT),
212 CONST (SCT_EIT_PRESENT_OTHER),
213 CONST (SCT_EIT_SCHEDULE0),
214 CONST (SCT_EIT_SCHEDULE15),
215 CONST (SCT_EIT_SCHEDULE_OTHER0),
216 CONST (SCT_EIT_SCHEDULE_OTHER15),
217 CONST (SCT_TDT),
218 CONST (SCT_RST),
219 CONST (SCT_ST),
220 CONST (SCT_TOT),
221 CONST (SCT_RNT),
222 CONST (SCT_CST),
223 CONST (SCT_RCT),
224 CONST (SCT_CIT),
225 CONST (SCT_MPE),
226 CONST (SCT_DIT),
227 CONST (SCT_SIT),
228
229 CONST (DT_service),
230 CONST (DT_country_availability),
231 CONST (DT_linkage),
232 CONST (DT_short_event),
233 CONST (DT_extended_event),
234 CONST (DT_component),
235 CONST (DT_content),
236 CONST (DT_private_data_specifier),
237 CONST (DT_short_smoothing_buffer),
238 CONST (DT_scrambling_indicator),
239 CONST (DT_PDC),
240 };
241
242 #define HVS_S(hv,struct,member) hv_store (hv, #member, sizeof (#member) - 1, newSVpv (struct.member, 0), 0)
243 #define HVS_I(hv,struct,member) hv_store (hv, #member, sizeof (#member) - 1, newSViv (struct.member), 0)
244 #define HVS(hv,name,sv) hv_store (hv, #name, sizeof (#name) - 1, (sv), 0)
245
246 static void
247 get_parameters (HV *hv, struct dvb_frontend_parameters *p, fe_type_t type)
248 {
249 HVS_I (hv, (*p), frequency);
250 HVS_I (hv, (*p), inversion);
251
252 switch (type)
253 {
254 case FE_QPSK:
255 HVS_I (hv, (*p).u.qpsk, symbol_rate);
256 HVS_I (hv, (*p).u.qpsk, fec_inner);
257 break;
258
259 case FE_QAM:
260 HVS_I (hv, (*p).u.qam, symbol_rate);
261 HVS_I (hv, (*p).u.qam, fec_inner);
262 HVS_I (hv, (*p).u.qam, modulation);
263 break;
264
265 case FE_OFDM:
266 HVS_I (hv, (*p).u.ofdm, bandwidth);
267 HVS_I (hv, (*p).u.ofdm, code_rate_HP);
268 HVS_I (hv, (*p).u.ofdm, code_rate_LP);
269 HVS_I (hv, (*p).u.ofdm, constellation);
270 HVS_I (hv, (*p).u.ofdm, transmission_mode);
271 break;
272 }
273 }
274
275 #define HVF_I(hv,struct,member) \
276 if (v = hv_fetch (hv, #member, sizeof (#member) - 1, 0)) \
277 struct.member = SvIV (*v); \
278 else \
279 croak ("required hash key '%s' not specified", #member);
280
281 static void
282 set_parameters (HV *hv, struct dvb_frontend_parameters *p, fe_type_t type)
283 {
284 SV **v;
285
286 HVF_I (hv, (*p), frequency);
287 HVF_I (hv, (*p), inversion);
288
289 switch (type)
290 {
291 case FE_QPSK:
292 HVF_I (hv, (*p).u.qpsk, symbol_rate);
293 HVF_I (hv, (*p).u.qpsk, fec_inner);
294 break;
295
296 case FE_QAM:
297 HVF_I (hv, (*p).u.qam, symbol_rate);
298 HVF_I (hv, (*p).u.qam, fec_inner);
299 HVF_I (hv, (*p).u.qam, modulation);
300 break;
301
302 case FE_OFDM:
303 HVF_I (hv, (*p).u.ofdm, bandwidth);
304 HVF_I (hv, (*p).u.ofdm, code_rate_HP);
305 HVF_I (hv, (*p).u.ofdm, code_rate_LP);
306 HVF_I (hv, (*p).u.ofdm, constellation);
307 HVF_I (hv, (*p).u.ofdm, transmission_mode);
308 break;
309 }
310 }
311
312 typedef unsigned char u8;
313
314 static SV *dec_sv;
315 static u8 *dec_data;
316 static long dec_ofs, dec_len8;
317 static U32 dec_field;
318 STRLEN dec_len;
319
320 #define decode_overflow (dec_ofs > dec_len8)
321
322 static void
323 decode_set (SV *data)
324 {
325 if (dec_sv)
326 SvREFCNT_dec (dec_sv);
327
328 dec_sv = newSVsv (data);
329 dec_data = SvPVbyte (dec_sv, dec_len);
330 dec_ofs = 0;
331 dec_len8 = dec_len << 3;
332 }
333
334 static U32
335 decode_field (int bits)
336 {
337 u8 *p = dec_data + (dec_ofs >> 3);
338 int frac = 8 - (dec_ofs & 7);
339 dec_ofs += bits;
340
341 if (decode_overflow)
342 return dec_field = 0;
343
344 U32 r = *p++;
345
346 r &= (1UL << frac) - 1;
347
348 if (bits < frac)
349 r >>= (frac - bits);
350 else
351 {
352 bits -= frac;
353
354 while (bits >= 8)
355 {
356 r = (r << 8) | *p++;
357 bits -= 8;
358 }
359
360 if (bits > 0)
361 r = (r << bits) | (*p >> (8 - bits));
362 }
363
364 return dec_field = r;
365 }
366
367 U32
368 clamp (U32 len)
369 {
370 return len < 4096 ? len : 0;
371 }
372
373 static SV *
374 text2sv (u8 *data, U32 len)
375 {
376 dSP;
377 SV *sv = newSVpvn (data, clamp (len));
378
379 PUSHMARK (SP);
380 XPUSHs (sv);
381 PUTBACK;
382 call_pv ("Linux::DVB::Decode::text", G_VOID);
383
384 return sv;
385 }
386
387 #define DEC_I(hv, bits, name) HVS (hv, name, newSViv (decode_field (bits)))
388 #define DEC_T(hv, bytes, name) HVS (hv, name, text2sv (dec_data + (dec_ofs >> 3), clamp (bytes))), dec_ofs += clamp (bytes) << 3
389 #define DEC_S(hv, bytes, name) HVS (hv, name, newSVpvn (dec_data + (dec_ofs >> 3), clamp (bytes))), dec_ofs += clamp (bytes) << 3
390
391 static AV *
392 decode_descriptors (long end)
393 {
394 AV *av = newAV ();
395
396 while (dec_ofs < end)
397 {
398 HV *hv = newHV ();
399 U8 type, len, len2;
400 AV *av2;
401 long end, end2;
402
403 av_push (av, newRV_noinc ((SV *)hv));
404
405 DEC_I (hv, 8, type);
406 type = dec_field;
407 len = decode_field (8);
408 end = dec_ofs + (len << 3);
409
410 if (end > dec_len8)
411 return av;
412
413 switch (type)
414 {
415 case DT_service:
416 DEC_I (hv, 8, service_type);
417 len2 = decode_field (8); DEC_T (hv, len2, service_provider_name);
418 len2 = decode_field (8); DEC_T (hv, len2, service_name);
419 break;
420
421 case DT_country_availability:
422 DEC_I (hv, 1, country_availability_flag);
423 decode_field (7);
424
425 DEC_S (hv, (end - dec_ofs) >> 3, private_data);
426 //while (dec_ofs + 24 <= end)
427 // av_push (av,
428 break;
429
430 case DT_linkage:
431 DEC_I (hv, 16, transport_stream_id);
432 DEC_I (hv, 16, original_network_id);
433 DEC_I (hv, 16, service_id);
434 DEC_I (hv, 8, linkage_type);
435
436 if (dec_field == 8)
437 {
438 U32 hot, org;
439
440 DEC_I (hv, 8, hand_over_type); hot = dec_field;
441 decode_field (3);
442 DEC_I (hv, 1, origin_type); org = dec_field;
443
444 if (hot > 0x00 && hot < 0x04)
445 DEC_I (hv, 16, network_id);
446
447 if (org == 0)
448 DEC_I (hv, 16, initial_service_id);
449 }
450
451 DEC_S (hv, (end - dec_ofs) >> 3, private_data);
452 break;
453
454 case DT_PDC:
455 decode_field (4);
456 DEC_I (hv, 20, programme_identification_label);
457 break;
458
459 case DT_component:
460 decode_field (4);
461 DEC_I (hv, 4, stream_content);
462 DEC_I (hv, 8, component_type);
463 DEC_I (hv, 8, component_tag);
464 DEC_S (hv, 3, ISO_639_language_code);
465 DEC_T (hv, (end - dec_ofs) >> 3, text);
466 break;
467
468 case DT_short_event:
469 DEC_S (hv, 3, ISO_639_language_code);
470 len2 = decode_field (8); DEC_T (hv, len2, event_name);
471 len2 = decode_field (8); DEC_T (hv, len2, text);
472 break;
473
474 case DT_extended_event:
475 DEC_I (hv, 4, descriptor_number);
476 DEC_I (hv, 4, last_descriptor_number);
477 DEC_S (hv, 3, ISO_639_language_code);
478
479 len2 = decode_field (8); end2 = dec_ofs + (len2 << 3);
480 av2 = newAV ();
481 HVS (hv, items, newRV_noinc ((SV *)av2));
482
483 while (dec_ofs < end2)
484 {
485 AV *av3 = newAV ();
486 len2 = decode_field (8); av_push (av3, text2sv (dec_data + (dec_ofs >> 3), len2)), dec_ofs += len << 3;
487 len2 = decode_field (8); av_push (av3, text2sv (dec_data + (dec_ofs >> 3), len2)), dec_ofs += len << 3;
488
489 av_push (av2, newRV_noinc ((SV *)av3));
490 }
491
492 len2 = decode_field (8); DEC_T (hv, len2, text);
493 break;
494
495 case DT_content:
496 av2 = newAV ();
497 HVS (hv, items, newRV_noinc ((SV *)av2));
498
499 while (dec_ofs < end)
500 {
501 HV *ev = newHV ();
502
503 DEC_I (ev, 4, content_nibble_level_1);
504 DEC_I (ev, 4, content_nibble_level_2);
505 DEC_I (ev, 4, user_nibble_1);
506 DEC_I (ev, 4, user_nibble_2);
507
508 av_push (av2, newRV_noinc ((SV *)ev));
509 }
510
511 break;
512
513 case DT_private_data_specifier:
514 DEC_I (hv, 32, private_data_specifier);
515 break;
516
517 default:
518 //fprintf (stderr, "UNKXXX %x\n", type);//D
519
520 case 0:
521 case 0x80:
522 case 0x81:
523 case 0x82:
524 case 0x83:
525 case 0x84:
526 case 0x85:
527 case 0x8d:
528 case 0x8e:
529 case 0xb2:
530 DEC_S (hv, len, raw_data);
531 break;
532 }
533
534 dec_ofs = end; // re-sync, in case of problems
535 }
536
537 return av;
538 }
539
540 MODULE = Linux::DVB PACKAGE = Linux::DVB
541
542 PROTOTYPES: DISABLE
543
544 void
545 _consts ()
546 PPCODE:
547 const struct consts *c;
548 for (c = consts;
549 c < consts + sizeof (consts) / sizeof (consts[0]);
550 c++)
551 {
552 XPUSHs (sv_2mortal (newSVpv (c->name, 0)));
553 XPUSHs (sv_2mortal (newSViv (c->value)));
554 }
555
556 MODULE = Linux::DVB PACKAGE = Linux::DVB::Frontend
557
558 SV *
559 _frontend_info (int fd)
560 CODE:
561 struct dvb_frontend_info fi;
562 HV *hv;
563
564 if (ioctl (fd, FE_GET_INFO, &fi) < 0)
565 XSRETURN_UNDEF;
566
567 hv = newHV ();
568 HVS_S (hv, fi, name);
569 HVS_I (hv, fi, type);
570 HVS_I (hv, fi, type);
571 HVS_I (hv, fi, frequency_min);
572 HVS_I (hv, fi, frequency_max);
573 HVS_I (hv, fi, frequency_stepsize);
574 HVS_I (hv, fi, frequency_tolerance);
575 HVS_I (hv, fi, symbol_rate_min);
576 HVS_I (hv, fi, symbol_rate_max);
577 HVS_I (hv, fi, symbol_rate_tolerance);
578 HVS_I (hv, fi, notifier_delay);
579 HVS_I (hv, fi, caps);
580
581 RETVAL = (SV *)newRV_noinc ((SV *)hv);
582 OUTPUT:
583 RETVAL
584
585 long
586 _read_status (int fd)
587 CODE:
588 fe_status_t st;
589
590 if (ioctl (fd, FE_READ_STATUS, &st) < 0)
591 XSRETURN_UNDEF;
592
593 RETVAL = st;
594 OUTPUT:
595 RETVAL
596
597 U32
598 _read_ber (int fd)
599 CODE:
600 uint32_t ber;
601 if (ioctl (fd, FE_READ_BER, &ber) < 0)
602 XSRETURN_UNDEF;
603
604 RETVAL = ber;
605 OUTPUT:
606 RETVAL
607
608 U32
609 _read_snr (int fd)
610 CODE:
611 uint32_t ber;
612 if (ioctl (fd, FE_READ_SNR, &ber) < 0)
613 XSRETURN_UNDEF;
614
615 RETVAL = ber;
616 OUTPUT:
617 RETVAL
618
619
620 I16
621 _signal_strength (int fd)
622 CODE:
623 int16_t st;
624 if (ioctl (fd, FE_READ_SIGNAL_STRENGTH, &st) < 0)
625 XSRETURN_UNDEF;
626
627 RETVAL = st;
628 OUTPUT:
629 RETVAL
630
631
632 U32
633 _uncorrected_blocks (int fd)
634 CODE:
635 uint32_t ubl;
636 if (ioctl (fd, FE_READ_UNCORRECTED_BLOCKS, &ubl) < 0)
637 XSRETURN_UNDEF;
638
639 RETVAL = ubl;
640 OUTPUT:
641 RETVAL
642
643 int
644 _set (int fd, SV *parameters, int type)
645 CODE:
646 struct dvb_frontend_parameters p;
647
648 if (!SvROK (parameters) || SvTYPE (SvRV (parameters)) != SVt_PVHV)
649 croak ("Linux::DVB::Frontend::set requires a hash as argument");
650
651 set_parameters ((HV *)SvRV (parameters), &p, type);
652
653 if (ioctl (fd, FE_SET_FRONTEND, &p) < 0)
654 XSRETURN_UNDEF;
655
656 RETVAL = 1;
657 OUTPUT:
658 RETVAL
659
660 SV *
661 _get (int fd, int type)
662 CODE:
663 struct dvb_frontend_parameters p;
664 HV *hv;
665
666 if (ioctl (fd, FE_GET_FRONTEND, &p) < 0)
667 XSRETURN_UNDEF;
668
669 hv = newHV ();
670 get_parameters (hv, &p, type);
671 RETVAL = (SV *)newRV_noinc ((SV *)hv);
672 OUTPUT:
673 RETVAL
674
675 SV *
676 _event (int fd, int type)
677 CODE:
678 struct dvb_frontend_event e;
679 HV *hv;
680
681 if (ioctl (fd, FE_GET_EVENT, &e) < 0)
682 XSRETURN_UNDEF;
683
684 hv = newHV ();
685 HVS_I (hv, e, status);
686 get_parameters (hv, &e.parameters, type);
687 RETVAL = (SV *)newRV_noinc ((SV *)hv);
688 OUTPUT:
689 RETVAL
690
691 MODULE = Linux::DVB PACKAGE = Linux::DVB::Demux
692
693 int
694 _start (int fd)
695 ALIAS:
696 _stop = 1
697 CODE:
698 if (ioctl (fd, ix ? DMX_STOP : DMX_START, 0) < 0)
699 XSRETURN_UNDEF;
700
701 RETVAL = 1;
702 OUTPUT:
703 RETVAL
704
705 int
706 _filter (int fd, U16 pid, SV *filter, SV *mask, U32 timeout = 0, U32 flags = DMX_CHECK_CRC)
707 CODE:
708 struct dmx_sct_filter_params p;
709 STRLEN l;
710 char *s;
711
712 memset (&p.filter, 0, sizeof (p.filter));
713
714 p.pid = pid;
715 s = SvPVbyte (filter, l); if (l > DMX_FILTER_SIZE) l = DMX_FILTER_SIZE; memcpy (p.filter.filter, s, l);
716 s = SvPVbyte (mask , l); if (l > DMX_FILTER_SIZE) l = DMX_FILTER_SIZE; memcpy (p.filter.mask , s, l);
717 p.timeout = timeout;
718 p.flags = flags;
719 if (ioctl (fd, DMX_SET_FILTER, &p) < 0)
720 XSRETURN_UNDEF;
721
722 RETVAL = 1;
723 OUTPUT:
724 RETVAL
725
726 int
727 _pes_filter (int fd, U16 pid, long input, long output, long type, U32 flags = 0)
728 CODE:
729 struct dmx_pes_filter_params p;
730
731 p.pid = pid;
732 p.input = input;
733 p.output = output;
734 p.pes_type = type;
735 p.flags = flags;
736 if (ioctl (fd, DMX_SET_PES_FILTER, &p) < 0)
737 XSRETURN_UNDEF;
738
739 RETVAL = 1;
740 OUTPUT:
741 RETVAL
742
743 int
744 _buffer (int fd, unsigned long size)
745 CODE:
746
747 if (ioctl (fd, DMX_SET_BUFFER_SIZE, size) < 0)
748 XSRETURN_UNDEF;
749
750 RETVAL = 1;
751 OUTPUT:
752 RETVAL
753
754 MODULE = Linux::DVB PACKAGE = Linux::DVB::Decode PREFIX = decode_
755
756 void
757 set (SV *data)
758 CODE:
759
760 int
761 len ()
762 CODE:
763 RETVAL = (dec_ofs + 7) >> 3;
764 OUTPUT:
765 RETVAL
766
767 U32
768 field (int bits)
769
770 SV *
771 si (SV *stream)
772 CODE:
773 HV *hv = newHV ();
774
775 U8 table_id;
776 U16 length;
777 long end;
778
779 decode_set (stream);
780
781 do {
782 DEC_I (hv, 8, table_id);
783 table_id = dec_field;
784 } while (table_id == 0xff);
785
786 DEC_I (hv, 1, section_syntax_indicator);
787 decode_field (1);
788 decode_field (2);
789
790 length = decode_field (12);
791 end = dec_ofs + (length << 3);
792
793 switch (table_id)
794 {
795 case SCT_EIT_PRESENT:
796 case SCT_EIT_PRESENT_OTHER:
797 case SCT_EIT_SCHEDULE0...SCT_EIT_SCHEDULE15: //GCC
798 case SCT_EIT_SCHEDULE_OTHER0...SCT_EIT_SCHEDULE_OTHER15: //GCC
799 DEC_I (hv, 16, service_id);
800 decode_field (2);
801 DEC_I (hv, 5, version_number);
802 DEC_I (hv, 1, current_next_indicator);
803 DEC_I (hv, 8, section_number);
804 DEC_I (hv, 8, last_section_number);
805 DEC_I (hv, 16, transport_stream_id);
806 DEC_I (hv, 16, original_network_id);
807 DEC_I (hv, 8, segment_last_section_number);
808 DEC_I (hv, 8, last_table_id);
809
810 AV *events = newAV ();
811 HVS (hv, events, newRV_noinc ((SV *)events));
812
813 while (end - dec_ofs > 32)
814 {
815 long dll;
816 AV *desc;
817 HV *ev = newHV ();
818 av_push (events, newRV_noinc ((SV *)ev));
819
820 DEC_I (ev, 16, event_id);
821 DEC_I (ev, 16, start_time_mjd);
822 DEC_I (ev, 24, start_time_hms);
823 DEC_I (ev, 24, duration);
824 DEC_I (ev, 3, running_status);
825 DEC_I (ev, 1, free_CA_mode);
826
827 dll = dec_ofs + (decode_field (12) << 3);
828
829 desc = decode_descriptors (dll);
830 HVS (ev, descriptors, newRV_noinc ((SV *)desc));
831 }
832
833 decode_field (32); // skip CRC
834
835 break;
836
837 case SCT_SDT:
838 case SCT_SDT_OTHER:
839 DEC_I (hv, 16, transport_stream_id);
840 decode_field (2);
841 DEC_I (hv, 5, version_number);
842 DEC_I (hv, 1, current_next_indicator);
843 DEC_I (hv, 8, section_number);
844 DEC_I (hv, 8, last_section_number);
845 DEC_I (hv, 16, original_network_id);
846 decode_field (8);
847
848 AV *services = newAV ();
849 HVS (hv, services, newRV_noinc ((SV *)services));
850
851 while (end - dec_ofs > 32)
852 {
853 HV *ev = newHV ();
854 U32 dll;
855 AV *desc;
856 av_push (services, newRV_noinc ((SV *)ev));
857
858 DEC_I (ev, 16, service_id);
859 decode_field (6);
860 DEC_I (ev, 1, EIT_schedule_flags);
861 DEC_I (ev, 1, EIT_present_following_flag);
862 DEC_I (ev, 3, running_status);
863 DEC_I (ev, 1, free_CA_mode);
864
865 dll = dec_ofs + (decode_field (12) << 3);
866
867 desc = decode_descriptors (dll);
868 HVS (ev, descriptors, newRV_noinc ((SV *)desc));
869 }
870
871 decode_field (32); // skip CRC
872 break;
873
874 default:
875 DEC_S (hv, length, raw_data);
876 break;
877 }
878
879 if (decode_overflow)
880 {
881 SvREFCNT_dec (hv);
882 XSRETURN_UNDEF;
883 }
884
885 sv_chop (stream, SvPVX (stream) + ((dec_ofs + 7) >> 3));
886
887 RETVAL = (SV *)newRV_noinc ((SV *)hv);
888 OUTPUT:
889 RETVAL
890