ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Linux-DVB/DVB.xs
(Generate patch)

Comparing Linux-DVB/DVB.xs (file contents):
Revision 1.3 by root, Sun Apr 3 02:16:05 2005 UTC vs.
Revision 1.4 by root, Tue Apr 5 03:42:21 2005 UTC

8#include <linux/dvb/dmx.h> 8#include <linux/dvb/dmx.h>
9 9
10#define CONST(name) { #name, name } 10#define CONST(name) { #name, name }
11 11
12enum { 12enum {
13 SCT_PAT = 0x00, 13 SCT_PAT = 0x00,
14 SCT_CAT = 0x01, 14 SCT_CAT = 0x01,
15 SCT_PMT = 0x02, 15 SCT_PMT = 0x02,
16 SCT_TSDT = 0x03, 16 SCT_TSDT = 0x03,
17 SCT_NIT = 0x40,//TODO 17 SCT_NIT = 0x40,//TODO
18 SCT_NIT_OTHER = 0x41, 18 SCT_NIT_OTHER = 0x41,
19 SCT_SDT = 0x42, 19 SCT_SDT = 0x42,
20 SCT_SDT_OTHER = 0x46, 20 SCT_SDT_OTHER = 0x46,
21 SCT_BAT = 0x4a,//TODO 21 SCT_BAT = 0x4a,//TODO
22 SCT_EIT_PRESENT = 0x4e, 22 SCT_EIT_PRESENT = 0x4e,
23 SCT_EIT_PRESENT_OTHER = 0x4f, 23 SCT_EIT_PRESENT_OTHER = 0x4f,
24 SCT_EIT_SCHEDULE0 = 0x50, 24 SCT_EIT_SCHEDULE0 = 0x50,
25 SCT_EIT_SCHEDULE15 = 0x5f, 25 SCT_EIT_SCHEDULE15 = 0x5f,
26 SCT_EIT_SCHEDULE_OTHER0 = 0x60, 26 SCT_EIT_SCHEDULE_OTHER0 = 0x60,
27 SCT_EIT_SCHEDULE_OTHER15 = 0x6f, 27 SCT_EIT_SCHEDULE_OTHER15 = 0x6f,
28 SCT_TDT = 0x70, 28 SCT_TDT = 0x70,
29 SCT_RST = 0x71, 29 SCT_RST = 0x71,
30 SCT_ST = 0x72, 30 SCT_ST = 0x72,
31 SCT_TOT = 0x73, 31 SCT_TOT = 0x73,
32 SCT_RNT = 0x74, 32 SCT_RNT = 0x74,
33 SCT_CST = 0x75, 33 SCT_CST = 0x75,
34 SCT_RCT = 0x76, 34 SCT_RCT = 0x76,
35 SCT_CIT = 0x77, 35 SCT_CIT = 0x77,
36 SCT_MPE = 0x78, 36 SCT_MPE = 0x78,
37 SCT_DIT = 0x7e, 37 SCT_DIT = 0x7e,
38 SCT_SIT = 0x7f, 38 SCT_SIT = 0x7f,
39}; 39};
40 40
41enum { 41enum {
42 DT_network_name = 0x40,
43 DT_service_list = 0x41,
44 DT_satellite_delivery_system = 0x43,
45 DT_cable_delivery_system = 0x44,
42 DT_service = 0x48, 46 DT_service = 0x48,
43 DT_country_availability = 0x49, 47 DT_country_availability = 0x49,
44 DT_linkage = 0x4a, 48 DT_linkage = 0x4a,
45 DT_short_event = 0x4d, 49 DT_short_event = 0x4d,
46 DT_extended_event = 0x4e, //NYI 50 DT_extended_event = 0x4e, //NYI
47 DT_component = 0x50, 51 DT_component = 0x50,
48 DT_content = 0x54, 52 DT_content = 0x54,
53 DT_terrestrial_delivery_system = 0x5A,
49 DT_private_data_specifier = 0x5f, 54 DT_private_data_specifier = 0x5f,
50 DT_short_smoothing_buffer = 0x61, //NYI 55 DT_short_smoothing_buffer = 0x61, //NYI
51 DT_scrambling_indicator = 0x65, //NYI 56 DT_scrambling_indicator = 0x65, //NYI
52 DT_PDC = 0x69, 57 DT_PDC = 0x69,
53}; 58};
54 59
55static const struct consts { 60static const struct consts {
56 const char *name; 61 const char *name;
57 const long value; 62 const long value;
224 CONST (SCT_CIT), 229 CONST (SCT_CIT),
225 CONST (SCT_MPE), 230 CONST (SCT_MPE),
226 CONST (SCT_DIT), 231 CONST (SCT_DIT),
227 CONST (SCT_SIT), 232 CONST (SCT_SIT),
228 233
234 CONST (DT_network_name),
235 CONST (DT_service_list),
236 CONST (DT_satellite_delivery_system),
237 CONST (DT_cable_delivery_system),
229 CONST (DT_service), 238 CONST (DT_service),
230 CONST (DT_country_availability), 239 CONST (DT_country_availability),
231 CONST (DT_linkage), 240 CONST (DT_linkage),
232 CONST (DT_short_event), 241 CONST (DT_short_event),
233 CONST (DT_extended_event), 242 CONST (DT_extended_event),
234 CONST (DT_component), 243 CONST (DT_component),
235 CONST (DT_content), 244 CONST (DT_content),
245 CONST (DT_terrestrial_delivery_system),
236 CONST (DT_private_data_specifier), 246 CONST (DT_private_data_specifier),
237 CONST (DT_short_smoothing_buffer), 247 CONST (DT_short_smoothing_buffer),
238 CONST (DT_scrambling_indicator), 248 CONST (DT_scrambling_indicator),
239 CONST (DT_PDC), 249 CONST (DT_PDC),
240}; 250};
365} 375}
366 376
367U32 377U32
368clamp (U32 len) 378clamp (U32 len)
369{ 379{
370 return len < 4096 ? len : 0; 380 return len < 4096
381 && len <= dec_len8 - (dec_ofs >> 3) + 1 /* +1 to detect overflows */
382 ? len : 0;
383}
384
385/* works on SvPOK strings ONLY */
386void
387safe_sv_chop (SV *sv, STRLEN count)
388{
389 if ((U32)count >= (U32)SvCUR (sv))
390 SvCUR_set (sv, 0);
391 else
392 sv_chop (sv, SvPVX (sv) + count);
393}
394
395U32
396bcd_to_int (U32 bcd_number)
397{
398 U32 result = 0;
399 U32 multiplicator = 1;
400
401 while (bcd_number != 0)
402 {
403 result += (bcd_number & 0x0f) * multiplicator;
404 bcd_number >>= 4;
405 multiplicator *= 10;
406 }
407
408 return result;
371} 409}
372 410
373static SV * 411static SV *
374text2sv (u8 *data, U32 len) 412text2sv (u8 *data, U32 len)
375{ 413{
410 if (end > dec_len8) 448 if (end > dec_len8)
411 return av; 449 return av;
412 450
413 switch (type) 451 switch (type)
414 { 452 {
453 case DT_network_name:
454 DEC_T (hv, (end - dec_ofs) >> 3, network_name);
455 break;
456
457 case DT_service_list:
458 {
459 AV *services = newAV ();
460 HVS (hv, services, newRV_noinc ((SV *)services));
461
462 while (dec_ofs < end)
463 {
464 HV *sv = newHV ();
465 av_push (services, newRV_noinc ((SV *)sv));
466
467 DEC_I (sv, 16, service_id);
468 DEC_I (sv, 8, service_type);
469
470 }
471 }
472
473 break;
474
475 case DT_satellite_delivery_system:
476 HVS (hv, frequency, newSVuv (bcd_to_int (decode_field (32))));
477 HVS (hv, orbital_position, newSVnv (bcd_to_int (decode_field (32)) / 10));
478 DEC_I (hv, 1, west_east_flag);
479 DEC_I (hv, 2, polarization);
480 DEC_I (hv, 5, modulation);
481 HVS (hv, symbol_rate, newSVuv (bcd_to_int (decode_field (28))));
482 DEC_I (hv, 4, fec_inner);
483 break;
484
485 case DT_cable_delivery_system:
486 {
487 I16 qam_modulation = -1;
488
489 HVS (hv, frequency, newSVuv (bcd_to_int (decode_field (32))));
490 decode_field (12); // reserved
491 DEC_I (hv, 4, fec_outer);
492
493 DEC_I (hv, 8, modulation);
494
495 if (dec_field >= 1 && dec_field <= 5)
496 qam_modulation = 1 << dec_field + 3;
497
498 HVS (hv, modulation_qam, newSViv (qam_modulation));
499
500 HVS (hv, symbol_rate, newSVuv (bcd_to_int (decode_field (28))));
501 DEC_I (hv, 4, fec_inner);
502
503 break;
504 }
505
415 case DT_service: 506 case DT_service:
416 DEC_I (hv, 8, service_type); 507 DEC_I (hv, 8, service_type);
417 len2 = decode_field (8); DEC_T (hv, len2, service_provider_name); 508 len2 = decode_field (8); DEC_T (hv, len2, service_provider_name);
418 len2 = decode_field (8); DEC_T (hv, len2, service_name); 509 len2 = decode_field (8); DEC_T (hv, len2, service_name);
419 break; 510 break;
507 598
508 av_push (av2, newRV_noinc ((SV *)ev)); 599 av_push (av2, newRV_noinc ((SV *)ev));
509 } 600 }
510 601
511 break; 602 break;
603
604 case DT_terrestrial_delivery_system:
605 {
606 I8 bandwidth_mhz = -1;
607
608 HVS (hv, centre_frequency, newSVuv (decode_field (32) * 10));
609
610 DEC_I (hv, 3, bandwidth);
611
612 if (dec_field <= 3)
613 bandwidth_mhz = 8 - dec_field;
614
615 HVS (hv, bandwidth_mhz, newSViv (bandwidth_mhz));
616
617 DEC_I (hv, 1, priority);
618 DEC_I (hv, 1, time_slicing_indicator);
619 DEC_I (hv, 1, mpe_fec_indicator);
620 decode_field (2); // reserved
621 DEC_I (hv, 2, constellation);
622 DEC_I (hv, 3, hierarchy_information);
623 DEC_I (hv, 3, code_rate_hp_stream);
624 DEC_I (hv, 3, code_rate_lp_stream);
625 DEC_I (hv, 2, guard_interval);
626 DEC_I (hv, 2, transmission_mode);
627 DEC_I (hv, 1, other_frequency_use);
628 decode_field (32);
629 }
630 break;
512 631
513 case DT_private_data_specifier: 632 case DT_private_data_specifier:
514 DEC_I (hv, 32, private_data_specifier); 633 DEC_I (hv, 32, private_data_specifier);
515 break; 634 break;
516 635
770SV * 889SV *
771si (SV *stream) 890si (SV *stream)
772 CODE: 891 CODE:
773 HV *hv = newHV (); 892 HV *hv = newHV ();
774 893
894 int syntax_indicator;
775 U8 table_id; 895 U8 table_id;
776 U16 length; 896 U16 length;
777 long end; 897 long end;
778 898
779 decode_set (stream); 899 decode_set (stream);
781 do { 901 do {
782 DEC_I (hv, 8, table_id); 902 DEC_I (hv, 8, table_id);
783 table_id = dec_field; 903 table_id = dec_field;
784 } while (table_id == 0xff); 904 } while (table_id == 0xff);
785 905
786 DEC_I (hv, 1, section_syntax_indicator); 906 syntax_indicator = decode_field (1);
907 HVS (hv, section_syntax_indicator, newSViv (syntax_indicator));
908
787 decode_field (1); 909 decode_field (1);
788 decode_field (2); 910 decode_field (2);
789 911
790 length = decode_field (12); 912 length = decode_field (12);
791 end = dec_ofs + (length << 3); 913 end = dec_ofs + (length << 3);
792 914
915 if (syntax_indicator)
916 {
793 switch (table_id) 917 switch (table_id)
794 { 918 {
919 case SCT_NIT:
920 {
921 U16 descriptor_end_offset;
922
923 DEC_I (hv, 16, network_id);
924 decode_field (2); // reserved
925 DEC_I (hv, 5, version_number);
926 DEC_I (hv, 1, current_next_indicator);
927 DEC_I (hv, 8, section_number);
928 DEC_I (hv, 8, last_section_number);
929 decode_field (4); // reserved
930
931 AV *desc;
932 descriptor_end_offset = dec_ofs + (decode_field (12) << 3);
933 desc = decode_descriptors (descriptor_end_offset);
934 HVS (hv,network_descriptors, newRV_noinc ((SV *)desc));
935
936 decode_field (4); //reserved
937 decode_field (12); // Skip length, we read until the end
938
939 AV *events = newAV ();
940 HVS (hv, events, newRV_noinc ((SV *)events));
941 while (end - dec_ofs > 32)
942 {
943 long dll;
944 HV *ev = newHV ();
945 av_push (events, newRV_noinc ((SV *)ev));
946
947 DEC_I (ev, 16, transport_stream_id);
948 DEC_I (ev, 16, original_network_id);
949 decode_field (4);
950
951 dll = dec_ofs + (decode_field (12) << 3);
952 desc = decode_descriptors (dll);
953 HVS (ev, descriptors, newRV_noinc ((SV *)desc));
954 }
955
956 decode_field (32); // skip CRC
957 }
958
959 break;
960
795 case SCT_EIT_PRESENT: 961 case SCT_EIT_PRESENT:
796 case SCT_EIT_PRESENT_OTHER: 962 case SCT_EIT_PRESENT_OTHER:
797 case SCT_EIT_SCHEDULE0...SCT_EIT_SCHEDULE15: //GCC 963 case SCT_EIT_SCHEDULE0...SCT_EIT_SCHEDULE15: //GCC
798 case SCT_EIT_SCHEDULE_OTHER0...SCT_EIT_SCHEDULE_OTHER15: //GCC 964 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); 965 DEC_I (hv, 16, service_id);
859 decode_field (6); 966 decode_field (2);
860 DEC_I (ev, 1, EIT_schedule_flags); 967 DEC_I (hv, 5, version_number);
861 DEC_I (ev, 1, EIT_present_following_flag); 968 DEC_I (hv, 1, current_next_indicator);
969 DEC_I (hv, 8, section_number);
970 DEC_I (hv, 8, last_section_number);
971 DEC_I (hv, 16, transport_stream_id);
972 DEC_I (hv, 16, original_network_id);
973 DEC_I (hv, 8, segment_last_section_number);
974 DEC_I (hv, 8, last_table_id);
975
976 AV *events = newAV ();
977 HVS (hv, events, newRV_noinc ((SV *)events));
978
979 while (end - dec_ofs > 32)
980 {
981 long dll;
982 AV *desc;
983 HV *ev = newHV ();
984 av_push (events, newRV_noinc ((SV *)ev));
985
986 DEC_I (ev, 16, event_id);
987 DEC_I (ev, 16, start_time_mjd);
988 DEC_I (ev, 24, start_time_hms);
989 DEC_I (ev, 24, duration);
862 DEC_I (ev, 3, running_status); 990 DEC_I (ev, 3, running_status);
863 DEC_I (ev, 1, free_CA_mode); 991 DEC_I (ev, 1, free_CA_mode);
864 992
865 dll = dec_ofs + (decode_field (12) << 3); 993 dll = dec_ofs + (decode_field (12) << 3);
866 994
867 desc = decode_descriptors (dll); 995 desc = decode_descriptors (dll);
868 HVS (ev, descriptors, newRV_noinc ((SV *)desc)); 996 HVS (ev, descriptors, newRV_noinc ((SV *)desc));
869 } 997 }
870 998
871 decode_field (32); // skip CRC 999 decode_field (32); // skip CRC
1000
872 break; 1001 break;
873 1002
1003 case SCT_SDT:
1004 case SCT_SDT_OTHER:
1005 DEC_I (hv, 16, transport_stream_id);
1006 decode_field (2);
1007 DEC_I (hv, 5, version_number);
1008 DEC_I (hv, 1, current_next_indicator);
1009 DEC_I (hv, 8, section_number);
1010 DEC_I (hv, 8, last_section_number);
1011 DEC_I (hv, 16, original_network_id);
1012 decode_field (8);
1013
1014 AV *services = newAV ();
1015 HVS (hv, services, newRV_noinc ((SV *)services));
1016
1017 while (end - dec_ofs > 32)
1018 {
1019 HV *ev = newHV ();
1020 U32 dll;
1021 AV *desc;
1022 av_push (services, newRV_noinc ((SV *)ev));
1023
1024 DEC_I (ev, 16, service_id);
1025 decode_field (6);
1026 DEC_I (ev, 1, EIT_schedule_flags);
1027 DEC_I (ev, 1, EIT_present_following_flag);
1028 DEC_I (ev, 3, running_status);
1029 DEC_I (ev, 1, free_CA_mode);
1030
1031 dll = dec_ofs + (decode_field (12) << 3);
1032
1033 desc = decode_descriptors (dll);
1034 HVS (ev, descriptors, newRV_noinc ((SV *)desc));
1035 }
1036
1037 decode_field (32); // skip CRC
1038 break;
1039
874 default: 1040 default:
875 DEC_S (hv, length, raw_data); 1041 DEC_S (hv, length, raw_data);
876 break; 1042 break;
1043 }
1044
1045 if (decode_overflow)
1046 {
1047 SvREFCNT_dec (hv);
1048 safe_sv_chop (stream, (end + 7) >> 3);
1049 XSRETURN_UNDEF;
1050 }
1051
1052 safe_sv_chop (stream, (dec_ofs + 7) >> 3);
877 } 1053 }
878 1054 else
879 if (decode_overflow)
880 { 1055 {
881 SvREFCNT_dec (hv); 1056 SvREFCNT_dec (hv);
1057 safe_sv_chop (stream, (end + 7) >> 3);
882 XSRETURN_UNDEF; 1058 XSRETURN_UNDEF;
883 } 1059 }
884 1060
885 sv_chop (stream, SvPVX (stream) + ((dec_ofs + 7) >> 3));
886
887 RETVAL = (SV *)newRV_noinc ((SV *)hv); 1061 RETVAL = (SV *)newRV_noinc ((SV *)hv);
888 OUTPUT: 1062 OUTPUT:
889 RETVAL 1063 RETVAL
890 1064

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines