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

# User Rev Content
1 root 1.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 root 1.2 SCT_NIT = 0x40,//TODO
18 root 1.1 SCT_NIT_OTHER = 0x41,
19     SCT_SDT = 0x42,
20     SCT_SDT_OTHER = 0x46,
21 root 1.2 SCT_BAT = 0x4a,//TODO
22 root 1.1 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 root 1.2 DT_service = 0x48,
43     DT_country_availability = 0x49,
44     DT_linkage = 0x4a,
45 root 1.1 DT_short_event = 0x4d,
46 root 1.2 DT_extended_event = 0x4e, //NYI
47 root 1.1 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 root 1.2
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 root 1.1 };
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 root 1.2 #define HVS(hv,name,sv) hv_store (hv, #name, sizeof (#name) - 1, (sv), 0)
245 root 1.1
246     static void
247 root 1.3 get_parameters (HV *hv, struct dvb_frontend_parameters *p, fe_type_t type)
248 root 1.1 {
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 root 1.3 #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 root 1.1 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 root 1.3 U32
368     clamp (U32 len)
369     {
370     return len < 4096 ? len : 0;
371     }
372    
373 root 1.2 static SV *
374     text2sv (u8 *data, U32 len)
375     {
376     dSP;
377 root 1.3 SV *sv = newSVpvn (data, clamp (len));
378 root 1.2
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 root 1.3 #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 root 1.1
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 root 1.2 U8 type, len, len2;
400     AV *av2;
401     long end, end2;
402 root 1.1
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 root 1.2 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 root 1.1 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 root 1.2 DEC_T (hv, (end - dec_ofs) >> 3, text);
466 root 1.1 break;
467    
468     case DT_short_event:
469     DEC_S (hv, 3, ISO_639_language_code);
470 root 1.2 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 root 1.1 break;
494    
495     case DT_content:
496 root 1.3 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 root 1.1 break;
512    
513     case DT_private_data_specifier:
514     DEC_I (hv, 32, private_data_specifier);
515     break;
516 root 1.2
517 root 1.1 default:
518 root 1.3 //fprintf (stderr, "UNKXXX %x\n", type);//D
519    
520 root 1.1 case 0:
521     case 0x80:
522     case 0x81:
523     case 0x82:
524 root 1.2 case 0x83:
525 root 1.1 case 0x84:
526     case 0x85:
527 root 1.2 case 0x8d:
528     case 0x8e:
529     case 0xb2:
530 root 1.1 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 root 1.3 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 root 1.1 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 root 1.3 get_parameters (hv, &p, type);
671 root 1.1 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 root 1.3 get_parameters (hv, &e.parameters, type);
687 root 1.1 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 root 1.2 HVS (hv, events, newRV_noinc ((SV *)events));
812 root 1.1
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 root 1.2 HVS (ev, descriptors, newRV_noinc ((SV *)desc));
831 root 1.1 }
832    
833     decode_field (32); // skip CRC
834    
835     break;
836 root 1.2
837 root 1.1 case SCT_SDT:
838     case SCT_SDT_OTHER:
839 root 1.2 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 root 1.1
848 root 1.2 AV *services = newAV ();
849     HVS (hv, services, newRV_noinc ((SV *)services));
850 root 1.1
851     while (end - dec_ofs > 32)
852     {
853     HV *ev = newHV ();
854     U32 dll;
855 root 1.2 AV *desc;
856     av_push (services, newRV_noinc ((SV *)ev));
857 root 1.1
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 root 1.2 dll = dec_ofs + (decode_field (12) << 3);
866 root 1.1
867 root 1.2 desc = decode_descriptors (dll);
868     HVS (ev, descriptors, newRV_noinc ((SV *)desc));
869 root 1.1 }
870    
871     decode_field (32); // skip CRC
872     break;
873 root 1.2
874 root 1.1 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