… | |
… | |
12 | enum { |
12 | enum { |
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, |
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, |
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, |
… | |
… | |
37 | SCT_DIT = 0x7e, |
37 | SCT_DIT = 0x7e, |
38 | SCT_SIT = 0x7f, |
38 | SCT_SIT = 0x7f, |
39 | }; |
39 | }; |
40 | |
40 | |
41 | enum { |
41 | enum { |
|
|
42 | DT_service = 0x48, |
|
|
43 | DT_country_availability = 0x49, |
|
|
44 | DT_linkage = 0x4a, |
42 | DT_short_event = 0x4d, |
45 | DT_short_event = 0x4d, |
43 | DT_extended_event = 0x4e, |
46 | DT_extended_event = 0x4e, //NYI |
44 | DT_component = 0x50, |
47 | DT_component = 0x50, |
45 | DT_content = 0x54, |
48 | DT_content = 0x54, |
46 | DT_private_data_specifier = 0x5f, |
49 | DT_private_data_specifier = 0x5f, |
47 | DT_short_smoothing_buffer = 0x61, //NYI |
50 | DT_short_smoothing_buffer = 0x61, //NYI |
48 | DT_scrambling_indicator = 0x65, //NYI |
51 | DT_scrambling_indicator = 0x65, //NYI |
… | |
… | |
220 | CONST (SCT_RCT), |
223 | CONST (SCT_RCT), |
221 | CONST (SCT_CIT), |
224 | CONST (SCT_CIT), |
222 | CONST (SCT_MPE), |
225 | CONST (SCT_MPE), |
223 | CONST (SCT_DIT), |
226 | CONST (SCT_DIT), |
224 | CONST (SCT_SIT), |
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), |
225 | }; |
240 | }; |
226 | |
241 | |
227 | #define HVS_S(hv,struct,member) hv_store (hv, #member, sizeof (#member) - 1, newSVpv (struct.member, 0), 0) |
242 | #define HVS_S(hv,struct,member) hv_store (hv, #member, sizeof (#member) - 1, newSVpv (struct.member, 0), 0) |
228 | #define HVS_I(hv,struct,member) hv_store (hv, #member, sizeof (#member) - 1, newSViv (struct.member), 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) |
229 | |
245 | |
230 | static void |
246 | static void |
231 | set_parameters (HV *hv, struct dvb_frontend_parameters *p, fe_type_t type) |
247 | set_parameters (HV *hv, struct dvb_frontend_parameters *p, fe_type_t type) |
232 | { |
248 | { |
233 | HVS_I (hv, (*p), frequency); |
249 | HVS_I (hv, (*p), frequency); |
… | |
… | |
309 | } |
325 | } |
310 | |
326 | |
311 | return dec_field = r; |
327 | return dec_field = r; |
312 | } |
328 | } |
313 | |
329 | |
|
|
330 | static SV * |
|
|
331 | text2sv (u8 *data, U32 len) |
|
|
332 | { |
|
|
333 | dSP; |
|
|
334 | SV *sv = newSVpvn (data, len); |
|
|
335 | |
|
|
336 | PUSHMARK (SP); |
|
|
337 | XPUSHs (sv); |
|
|
338 | PUTBACK; |
|
|
339 | call_pv ("Linux::DVB::Decode::text", G_VOID); |
|
|
340 | |
|
|
341 | return sv; |
|
|
342 | } |
|
|
343 | |
314 | #define DEC_I(hv, bits, name) hv_store (hv, #name, sizeof (#name) - 1, newSViv (decode_field (bits)), 0) |
344 | #define DEC_I(hv, bits, name) HVS (hv, name, newSViv (decode_field (bits))) |
|
|
345 | #define DEC_T(hv, bytes, name) HVS (hv, name, text2sv (dec_data + (dec_ofs >> 3), (bytes))), dec_ofs += (bytes) << 3 |
315 | #define DEC_S(hv, bytes, name) hv_store (hv, #name, sizeof (#name) - 1, newSVpvn (dec_data + (dec_ofs >> 3), (bytes)), 0), dec_ofs += (bytes) << 3 |
346 | #define DEC_S(hv, bytes, name) HVS (hv, name, newSVpvn (dec_data + (dec_ofs >> 3), (bytes))), dec_ofs += (bytes) << 3 |
316 | |
347 | |
317 | static AV * |
348 | static AV * |
318 | decode_descriptors (long end) |
349 | decode_descriptors (long end) |
319 | { |
350 | { |
320 | AV *av = newAV (); |
351 | AV *av = newAV (); |
321 | |
352 | |
322 | while (dec_ofs < end) |
353 | while (dec_ofs < end) |
323 | { |
354 | { |
324 | HV *hv = newHV (); |
355 | HV *hv = newHV (); |
325 | U8 type, len, a; |
356 | U8 type, len, len2; |
|
|
357 | AV *av2; |
326 | long end; |
358 | long end, end2; |
327 | |
359 | |
328 | av_push (av, newRV_noinc ((SV *)hv)); |
360 | av_push (av, newRV_noinc ((SV *)hv)); |
329 | |
361 | |
330 | DEC_I (hv, 8, type); |
362 | DEC_I (hv, 8, type); |
331 | type = dec_field; |
363 | type = dec_field; |
332 | len = decode_field (8); |
364 | len = decode_field (8); |
333 | |
|
|
334 | end = dec_ofs + (len << 3); |
365 | end = dec_ofs + (len << 3); |
335 | |
366 | |
336 | if (end > dec_len8) |
367 | if (end > dec_len8) |
337 | return av; |
368 | return av; |
338 | |
369 | |
339 | switch (type) |
370 | switch (type) |
340 | { |
371 | { |
|
|
372 | case DT_service: |
|
|
373 | DEC_I (hv, 8, service_type); |
|
|
374 | len2 = decode_field (8); DEC_T (hv, len2, service_provider_name); |
|
|
375 | len2 = decode_field (8); DEC_T (hv, len2, service_name); |
|
|
376 | break; |
|
|
377 | |
|
|
378 | case DT_country_availability: |
|
|
379 | DEC_I (hv, 1, country_availability_flag); |
|
|
380 | decode_field (7); |
|
|
381 | |
|
|
382 | DEC_S (hv, (end - dec_ofs) >> 3, private_data); |
|
|
383 | //while (dec_ofs + 24 <= end) |
|
|
384 | // av_push (av, |
|
|
385 | break; |
|
|
386 | |
|
|
387 | case DT_linkage: |
|
|
388 | DEC_I (hv, 16, transport_stream_id); |
|
|
389 | DEC_I (hv, 16, original_network_id); |
|
|
390 | DEC_I (hv, 16, service_id); |
|
|
391 | DEC_I (hv, 8, linkage_type); |
|
|
392 | |
|
|
393 | if (dec_field == 8) |
|
|
394 | { |
|
|
395 | U32 hot, org; |
|
|
396 | |
|
|
397 | DEC_I (hv, 8, hand_over_type); hot = dec_field; |
|
|
398 | decode_field (3); |
|
|
399 | DEC_I (hv, 1, origin_type); org = dec_field; |
|
|
400 | |
|
|
401 | if (hot > 0x00 && hot < 0x04) |
|
|
402 | DEC_I (hv, 16, network_id); |
|
|
403 | |
|
|
404 | if (org == 0) |
|
|
405 | DEC_I (hv, 16, initial_service_id); |
|
|
406 | } |
|
|
407 | |
|
|
408 | DEC_S (hv, (end - dec_ofs) >> 3, private_data); |
|
|
409 | break; |
|
|
410 | |
341 | case DT_PDC: |
411 | case DT_PDC: |
342 | decode_field (4); |
412 | decode_field (4); |
343 | DEC_I (hv, 20, programme_identification_label); |
413 | DEC_I (hv, 20, programme_identification_label); |
344 | break; |
414 | break; |
345 | |
415 | |
… | |
… | |
347 | decode_field (4); |
417 | decode_field (4); |
348 | DEC_I (hv, 4, stream_content); |
418 | DEC_I (hv, 4, stream_content); |
349 | DEC_I (hv, 8, component_type); |
419 | DEC_I (hv, 8, component_type); |
350 | DEC_I (hv, 8, component_tag); |
420 | DEC_I (hv, 8, component_tag); |
351 | DEC_S (hv, 3, ISO_639_language_code); |
421 | DEC_S (hv, 3, ISO_639_language_code); |
352 | DEC_S (hv, (end - dec_ofs) >> 3, text); |
422 | DEC_T (hv, (end - dec_ofs) >> 3, text); |
353 | break; |
423 | break; |
354 | |
424 | |
355 | case DT_short_event: |
425 | case DT_short_event: |
356 | DEC_S (hv, 3, ISO_639_language_code); |
426 | DEC_S (hv, 3, ISO_639_language_code); |
357 | a = decode_field (8); DEC_S (hv, a, event_name); |
427 | len2 = decode_field (8); DEC_T (hv, len2, event_name); |
358 | a = decode_field (8); DEC_S (hv, a, text); |
428 | len2 = decode_field (8); DEC_T (hv, len2, text); |
|
|
429 | break; |
|
|
430 | |
|
|
431 | case DT_extended_event: |
|
|
432 | DEC_I (hv, 4, descriptor_number); |
|
|
433 | DEC_I (hv, 4, last_descriptor_number); |
|
|
434 | DEC_S (hv, 3, ISO_639_language_code); |
|
|
435 | |
|
|
436 | len2 = decode_field (8); end2 = dec_ofs + (len2 << 3); |
|
|
437 | av2 = newAV (); |
|
|
438 | HVS (hv, items, newRV_noinc ((SV *)av2)); |
|
|
439 | |
|
|
440 | while (dec_ofs < end2) |
|
|
441 | { |
|
|
442 | AV *av3 = newAV (); |
|
|
443 | len2 = decode_field (8); av_push (av3, text2sv (dec_data + (dec_ofs >> 3), len2)), dec_ofs += len << 3; |
|
|
444 | len2 = decode_field (8); av_push (av3, text2sv (dec_data + (dec_ofs >> 3), len2)), dec_ofs += len << 3; |
|
|
445 | |
|
|
446 | av_push (av2, newRV_noinc ((SV *)av3)); |
|
|
447 | } |
|
|
448 | |
|
|
449 | len2 = decode_field (8); DEC_T (hv, len2, text); |
359 | break; |
450 | break; |
360 | |
451 | |
361 | case DT_content: |
452 | case DT_content: |
362 | DEC_S (hv, len, content); |
453 | DEC_S (hv, len, content); |
363 | break; |
454 | break; |
364 | |
455 | |
365 | case DT_private_data_specifier: |
456 | case DT_private_data_specifier: |
366 | DEC_I (hv, 32, private_data_specifier); |
457 | DEC_I (hv, 32, private_data_specifier); |
367 | break; |
458 | break; |
368 | |
459 | |
369 | default: |
460 | default: |
370 | fprintf (stderr, "UNKXXX %x\n", type);//D |
461 | fprintf (stderr, "UNKXXX %x\n", type);//D |
371 | case 0: |
462 | case 0: |
372 | case DT_extended_event: |
|
|
373 | case 0x80: |
463 | case 0x80: |
374 | case 0x81: |
464 | case 0x81: |
375 | case 0x82: |
465 | case 0x82: |
|
|
466 | case 0x83: |
376 | case 0x84: |
467 | case 0x84: |
377 | case 0x85: |
468 | case 0x85: |
|
|
469 | case 0x8d: |
|
|
470 | case 0x8e: |
|
|
471 | case 0xb2: |
378 | DEC_S (hv, len, raw_data); |
472 | DEC_S (hv, len, raw_data); |
379 | break; |
473 | break; |
380 | } |
474 | } |
381 | |
475 | |
382 | dec_ofs = end; // re-sync, in case of problems |
476 | dec_ofs = end; // re-sync, in case of problems |
… | |
… | |
637 | DEC_I (hv, 16, original_network_id); |
731 | DEC_I (hv, 16, original_network_id); |
638 | DEC_I (hv, 8, segment_last_section_number); |
732 | DEC_I (hv, 8, segment_last_section_number); |
639 | DEC_I (hv, 8, last_table_id); |
733 | DEC_I (hv, 8, last_table_id); |
640 | |
734 | |
641 | AV *events = newAV (); |
735 | AV *events = newAV (); |
642 | hv_store (hv, "events", 6, newRV_noinc ((SV *)events), 0); |
736 | HVS (hv, events, newRV_noinc ((SV *)events)); |
643 | |
737 | |
644 | while (end - dec_ofs > 32) |
738 | while (end - dec_ofs > 32) |
645 | { |
739 | { |
646 | long dll; |
740 | long dll; |
647 | AV *desc; |
741 | AV *desc; |
… | |
… | |
656 | DEC_I (ev, 1, free_CA_mode); |
750 | DEC_I (ev, 1, free_CA_mode); |
657 | |
751 | |
658 | dll = dec_ofs + (decode_field (12) << 3); |
752 | dll = dec_ofs + (decode_field (12) << 3); |
659 | |
753 | |
660 | desc = decode_descriptors (dll); |
754 | desc = decode_descriptors (dll); |
661 | hv_store (ev, "descriptors", 11, newRV_noinc ((SV *)desc), 0); |
755 | HVS (ev, descriptors, newRV_noinc ((SV *)desc)); |
662 | } |
756 | } |
663 | |
757 | |
664 | decode_field (32); // skip CRC |
758 | decode_field (32); // skip CRC |
665 | |
759 | |
666 | break; |
760 | break; |
667 | #if 0 // service desc table |
761 | |
668 | case SCT_SDT: |
762 | case SCT_SDT: |
669 | case SCT_SDT_OTHER: |
763 | case SCT_SDT_OTHER: |
|
|
764 | DEC_I (hv, 16, transport_stream_id); |
|
|
765 | decode_field (2); |
|
|
766 | DEC_I (hv, 5, version_number); |
|
|
767 | DEC_I (hv, 1, current_next_indicator); |
|
|
768 | DEC_I (hv, 8, section_number); |
|
|
769 | DEC_I (hv, 8, last_section_number); |
|
|
770 | DEC_I (hv, 16, original_network_id); |
|
|
771 | decode_field (8); |
670 | |
772 | |
671 | AV *events = newAV (); |
773 | AV *services = newAV (); |
672 | hv_store (hv, "events", 0, newRV_noinc (events), 0); |
774 | HVS (hv, services, newRV_noinc ((SV *)services)); |
673 | |
775 | |
674 | while (end - dec_ofs > 32) |
776 | while (end - dec_ofs > 32) |
675 | { |
777 | { |
676 | HV *ev = newHV (); |
778 | HV *ev = newHV (); |
677 | U32 dll; |
779 | U32 dll; |
|
|
780 | AV *desc; |
678 | av_push (events, newRV_noinc (ev)); |
781 | av_push (services, newRV_noinc ((SV *)ev)); |
679 | |
782 | |
680 | DEC_I (ev, 16, service_id); |
783 | DEC_I (ev, 16, service_id); |
681 | decode_field (6); |
784 | decode_field (6); |
682 | DEC_I (ev, 1, EIT_schedule_flags); |
785 | DEC_I (ev, 1, EIT_schedule_flags); |
683 | DEC_I (ev, 1, EIT_present_following_flag); |
786 | DEC_I (ev, 1, EIT_present_following_flag); |
684 | DEC_I (ev, 3, running_status); |
787 | DEC_I (ev, 3, running_status); |
685 | DEC_I (ev, 1, free_CA_mode); |
788 | DEC_I (ev, 1, free_CA_mode); |
686 | |
789 | |
687 | dll = decode_field (12); |
790 | dll = dec_ofs + (decode_field (12) << 3); |
688 | |
791 | |
689 | DEC_I (ev, 1, free_CA_mode); |
792 | desc = decode_descriptors (dll); |
|
|
793 | HVS (ev, descriptors, newRV_noinc ((SV *)desc)); |
690 | } |
794 | } |
691 | |
795 | |
692 | decode_field (32); // skip CRC |
796 | decode_field (32); // skip CRC |
693 | //DEC_S (hv, length + 3 - (dec_ofs >> 3), raw_data); |
|
|
694 | break; |
797 | break; |
695 | #endif |
798 | |
696 | default: |
799 | default: |
697 | DEC_S (hv, length, raw_data); |
800 | DEC_S (hv, length, raw_data); |
698 | break; |
801 | break; |
699 | } |
802 | } |
700 | |
803 | |