Proper CableCARD/HDHomeRun Prime support » tvheadend_cablecard-4.3.patch
src/input/mpegts/dvb.h | ||
---|---|---|
421 | 421 |
DVB_TYPE_S, /* satellite */ |
422 | 422 |
DVB_TYPE_ATSC_T, /* terrestrial - north america */ |
423 | 423 |
DVB_TYPE_ATSC_C, /* cable - north america */ |
424 |
DVB_TYPE_CABLECARD, /* CableCARD - North America */ |
|
424 | 425 |
DVB_TYPE_ISDB_T, /* terrestrial - japan, brazil */ |
425 | 426 |
DVB_TYPE_ISDB_C, /* cable - japan, brazil */ |
426 | 427 |
DVB_TYPE_ISDB_S, /* satellite - japan, brazil */ |
... | ... | |
615 | 616 |
} layers[3]; |
616 | 617 |
} dvb_isdbt_config_t; |
617 | 618 | |
619 |
typedef struct dvb_fe_vchan { |
|
620 |
uint32_t num; |
|
621 |
uint16_t minor; |
|
622 |
char *name; |
|
623 |
} dvb_fe_vchan_t; |
|
624 | ||
618 | 625 |
typedef struct dvb_mux_conf |
619 | 626 |
{ |
620 | 627 |
dvb_fe_type_t dmc_fe_type; |
... | ... | |
633 | 640 |
dvb_ofdm_config_t dmc_fe_ofdm; |
634 | 641 |
dvb_isdbt_config_t dmc_fe_isdbt; |
635 | 642 |
} u; |
643 |
dvb_fe_vchan_t dmc_fe_vchan; |
|
636 | 644 | |
637 | 645 |
// For scan file configurations |
638 | 646 |
LIST_ENTRY(dvb_mux_conf) dmc_link; |
src/input/mpegts/dvb_support.c | ||
---|---|---|
683 | 683 |
{ "DVBC/ANNEX_A", DVB_SYS_DVBC_ANNEX_A }, |
684 | 684 |
{ "DVBC_ANNEX_A", DVB_SYS_DVBC_ANNEX_A }, |
685 | 685 |
{ "ATSC-C", DVB_SYS_DVBC_ANNEX_B }, |
686 |
{ "CableCARD", DVB_SYS_DVBC_ANNEX_B }, |
|
686 | 687 |
{ "DVBC/ANNEX_B", DVB_SYS_DVBC_ANNEX_B }, |
687 | 688 |
{ "DVBC_ANNEX_B", DVB_SYS_DVBC_ANNEX_B }, |
688 | 689 |
{ "DVB-C/ANNEX-C",DVB_SYS_DVBC_ANNEX_C }, |
... | ... | |
738 | 739 |
case DVB_SYS_DVBC_ANNEX_B: |
739 | 740 |
if (ln && idnode_is_instance(&ln->mn_id, &dvb_network_dvbc_class)) |
740 | 741 |
return DVB_TYPE_C; |
742 |
if (ln && idnode_is_instance(&ln->mn_id, &dvb_network_cablecard_class)) |
|
743 |
return DVB_TYPE_CABLECARD; |
|
741 | 744 |
else |
742 | 745 |
return DVB_TYPE_ATSC_C; |
743 | 746 |
case DVB_SYS_ISDBT: |
... | ... | |
946 | 949 |
dvb_str2val(pol); |
947 | 950 | |
948 | 951 |
const static struct strtab typetab[] = { |
949 |
{"DVB-T", DVB_TYPE_T}, |
|
950 |
{"DVB-C", DVB_TYPE_C}, |
|
951 |
{"DVB-S", DVB_TYPE_S}, |
|
952 |
{"ATSC-T", DVB_TYPE_ATSC_T}, |
|
953 |
{"ATSC-C", DVB_TYPE_ATSC_C}, |
|
954 |
{"ISDB-T", DVB_TYPE_ISDB_T}, |
|
955 |
{"ISDB-C", DVB_TYPE_ISDB_C}, |
|
956 |
{"ISDB-S", DVB_TYPE_ISDB_S}, |
|
957 |
{"DAB", DVB_TYPE_DAB}, |
|
958 |
{"DVBT", DVB_TYPE_T}, |
|
959 |
{"DVBC", DVB_TYPE_C}, |
|
960 |
{"DVBS", DVB_TYPE_S}, |
|
961 |
{"ATSC", DVB_TYPE_ATSC_T}, |
|
962 |
{"ATSCT", DVB_TYPE_ATSC_T}, |
|
963 |
{"ATSCC", DVB_TYPE_ATSC_C}, |
|
964 |
{"ISDBT", DVB_TYPE_ISDB_T}, |
|
965 |
{"ISDBC", DVB_TYPE_ISDB_C}, |
|
966 |
{"ISDBS", DVB_TYPE_ISDB_S} |
|
952 |
{"DVB-T", DVB_TYPE_T}, |
|
953 |
{"DVB-C", DVB_TYPE_C}, |
|
954 |
{"DVB-S", DVB_TYPE_S}, |
|
955 |
{"ATSC-T", DVB_TYPE_ATSC_T}, |
|
956 |
{"ATSC-C", DVB_TYPE_ATSC_C}, |
|
957 |
{"CableCARD", DVB_TYPE_CABLECARD}, |
|
958 |
{"ISDB-T", DVB_TYPE_ISDB_T}, |
|
959 |
{"ISDB-C", DVB_TYPE_ISDB_C}, |
|
960 |
{"ISDB-S", DVB_TYPE_ISDB_S}, |
|
961 |
{"DAB", DVB_TYPE_DAB}, |
|
962 |
{"DVBT", DVB_TYPE_T}, |
|
963 |
{"DVBC", DVB_TYPE_C}, |
|
964 |
{"DVBS", DVB_TYPE_S}, |
|
965 |
{"ATSC", DVB_TYPE_ATSC_T}, |
|
966 |
{"ATSCT", DVB_TYPE_ATSC_T}, |
|
967 |
{"ATSCC", DVB_TYPE_ATSC_C}, |
|
968 |
{"ISDBT", DVB_TYPE_ISDB_T}, |
|
969 |
{"ISDBC", DVB_TYPE_ISDB_C}, |
|
970 |
{"ISDBS", DVB_TYPE_ISDB_S} |
|
967 | 971 |
}; |
968 | 972 |
dvb_str2val(type); |
969 | 973 | |
... | ... | |
1081 | 1085 |
dvb_qam2str(dmc->dmc_fe_modulation)); |
1082 | 1086 |
} |
1083 | 1087 | |
1088 |
static int |
|
1089 |
dvb_mux_conf_str_cablecard(dvb_mux_conf_t *dmc, char *buf, size_t bufsize) |
|
1090 |
{ |
|
1091 |
if (!dmc->dmc_fe_vchan.minor) |
|
1092 |
return snprintf(buf, bufsize, "%s channel %u", |
|
1093 |
dvb_type2str(dmc->dmc_fe_type), |
|
1094 |
dmc->dmc_fe_vchan.num); |
|
1095 |
else |
|
1096 |
return snprintf(buf, bufsize, "%s channel %u.%u", |
|
1097 |
dvb_type2str(dmc->dmc_fe_type), |
|
1098 |
dmc->dmc_fe_vchan.num, |
|
1099 |
dmc->dmc_fe_vchan.minor); |
|
1100 |
} |
|
1101 | ||
1084 | 1102 |
static int |
1085 | 1103 |
dvb_mux_conf_str_isdb_t ( dvb_mux_conf_t *dmc, char *buf, size_t bufsize ) |
1086 | 1104 |
{ |
... | ... | |
1124 | 1142 |
return dvb_mux_conf_str_dvbs(dmc, buf, bufsize); |
1125 | 1143 |
case DVB_TYPE_ATSC_T: |
1126 | 1144 |
return dvb_mux_conf_str_atsc_t(dmc, buf, bufsize); |
1145 |
case DVB_TYPE_CABLECARD: |
|
1146 |
return dvb_mux_conf_str_cablecard(dmc, buf, bufsize); |
|
1127 | 1147 |
case DVB_TYPE_ISDB_T: |
1128 | 1148 |
return dvb_mux_conf_str_isdb_t(dmc, buf, bufsize); |
1129 | 1149 |
default: |
src/input/mpegts/mpegts_dvb.h | ||
---|---|---|
50 | 50 |
extern const idclass_t dvb_network_dvbs_class; |
51 | 51 |
extern const idclass_t dvb_network_atsc_t_class; |
52 | 52 |
extern const idclass_t dvb_network_atsc_c_class; |
53 |
extern const idclass_t dvb_network_cablecard_class; |
|
53 | 54 |
extern const idclass_t dvb_network_isdb_t_class; |
54 | 55 |
extern const idclass_t dvb_network_isdb_c_class; |
55 | 56 |
extern const idclass_t dvb_network_isdb_s_class; |
... | ... | |
88 | 89 |
extern const idclass_t dvb_mux_dvbs_class; |
89 | 90 |
extern const idclass_t dvb_mux_atsc_t_class; |
90 | 91 |
extern const idclass_t dvb_mux_atsc_c_class; |
92 |
extern const idclass_t dvb_mux_cablecard_class; |
|
91 | 93 |
extern const idclass_t dvb_mux_isdb_t_class; |
92 | 94 |
extern const idclass_t dvb_mux_isdb_c_class; |
93 | 95 |
extern const idclass_t dvb_mux_isdb_s_class; |
src/input/mpegts/mpegts_mux_dvb.c | ||
---|---|---|
129 | 129 |
return 0; |
130 | 130 |
} |
131 | 131 | |
132 |
static const void * |
|
133 |
dvb_mux_class_vchan_get(void *o) |
|
134 |
{ |
|
135 |
dvb_mux_t *lm = (dvb_mux_t *)o; |
|
136 | ||
137 |
if (!lm->lm_tuning.dmc_fe_vchan.minor) |
|
138 |
snprintf(prop_sbuf, PROP_SBUF_LEN, "%u", |
|
139 |
lm->lm_tuning.dmc_fe_vchan.num); |
|
140 |
else |
|
141 |
snprintf(prop_sbuf, PROP_SBUF_LEN, "%u.%u", |
|
142 |
lm->lm_tuning.dmc_fe_vchan.num, |
|
143 |
lm->lm_tuning.dmc_fe_vchan.minor); |
|
144 |
return &prop_sbuf_ptr; |
|
145 |
} |
|
146 | ||
147 |
static int |
|
148 |
dvb_mux_class_vchan_set(void *o, const void *v) |
|
149 |
{ |
|
150 |
dvb_mux_t *lm = (dvb_mux_t *)o; |
|
151 |
int r; |
|
152 | ||
153 |
r = sscanf(v, "%u%*[.-]%hu", |
|
154 |
&lm->lm_tuning.dmc_fe_vchan.num, |
|
155 |
&lm->lm_tuning.dmc_fe_vchan.minor); |
|
156 |
switch (r) { |
|
157 |
case 0: |
|
158 |
return 1; |
|
159 |
case 1: |
|
160 |
lm->lm_tuning.dmc_fe_vchan.minor = 0; |
|
161 |
} |
|
162 |
return 0; |
|
163 |
} |
|
164 | ||
132 | 165 |
const idclass_t dvb_mux_class = |
133 | 166 |
{ |
134 | 167 |
.ic_super = &mpegts_mux_class, |
... | ... | |
614 | 647 |
} |
615 | 648 |
}; |
616 | 649 | |
650 |
/* |
|
651 |
* CableCARD |
|
652 |
*/ |
|
653 |
const idclass_t dvb_mux_cablecard_class = |
|
654 |
{ |
|
655 |
.ic_super = &dvb_mux_class, |
|
656 |
.ic_class = "dvb_mux_cablecard", |
|
657 |
.ic_caption = N_("CableCARD multiplex"), |
|
658 |
.ic_properties = (const property_t[]){ |
|
659 |
{ |
|
660 |
.type = PT_STR, |
|
661 |
.id = "vchan", |
|
662 |
.name = N_("Channel"), |
|
663 |
.desc = N_("The channel on the cable provider's network."), |
|
664 |
.get = dvb_mux_class_vchan_get, |
|
665 |
.set = dvb_mux_class_vchan_set, |
|
666 |
}, |
|
667 |
{ |
|
668 |
.type = PT_U32, |
|
669 |
.id = "frequency", |
|
670 |
.name = N_("Frequency (Hz)"), |
|
671 |
.desc = N_("The frequency of the mux (in Hertz)."), |
|
672 |
.off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_freq), |
|
673 |
.opts = PO_RDONLY, |
|
674 |
}, |
|
675 |
{ |
|
676 |
.type = PT_STR, |
|
677 |
.id = "vchan_name", |
|
678 |
.name = N_("Callsign"), |
|
679 |
.desc = N_("The channel's name or callsign as set by the cable provider."), |
|
680 |
.off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_vchan.name), |
|
681 |
.opts = PO_RDONLY, |
|
682 |
}, |
|
683 |
{} |
|
684 |
} |
|
685 |
}; |
|
686 | ||
617 | 687 |
/* |
618 | 688 |
* ISDB-T |
619 | 689 |
*/ |
... | ... | |
1049 | 1119 |
dvb_network_t *ln = (dvb_network_t*)mm->mm_network; |
1050 | 1120 |
uint32_t freq = lm->lm_tuning.dmc_fe_freq, freq2; |
1051 | 1121 |
char extra[8], buf2[5], *p; |
1052 |
if (ln->ln_type == DVB_TYPE_S) { |
|
1053 |
const char *s = dvb_pol2str(lm->lm_tuning.u.dmc_fe_qpsk.polarisation); |
|
1054 |
if (s) extra[0] = *s; |
|
1055 |
extra[1] = '\0'; |
|
1122 | ||
1123 |
if (lm->lm_tuning.dmc_fe_type == DVB_TYPE_CABLECARD) { |
|
1124 |
if (!lm->lm_tuning.dmc_fe_vchan.minor) |
|
1125 |
snprintf(buf, len, "%u", lm->lm_tuning.dmc_fe_vchan.num); |
|
1126 |
else |
|
1127 |
snprintf(buf, len, "%u.%u", |
|
1128 |
lm->lm_tuning.dmc_fe_vchan.num, |
|
1129 |
lm->lm_tuning.dmc_fe_vchan.minor); |
|
1056 | 1130 |
} else { |
1131 |
if (ln->ln_type == DVB_TYPE_S) { |
|
1132 |
const char *s = dvb_pol2str(lm->lm_tuning.u.dmc_fe_qpsk.polarisation); |
|
1133 |
if (s) extra[0] = *s; |
|
1134 |
extra[1] = '\0'; |
|
1135 |
} else { |
|
1136 |
freq /= 1000; |
|
1137 |
strcpy(extra, "MHz"); |
|
1138 |
} |
|
1139 |
freq2 = freq % 1000; |
|
1057 | 1140 |
freq /= 1000; |
1058 |
strcpy(extra, "MHz"); |
|
1059 |
} |
|
1060 |
freq2 = freq % 1000; |
|
1061 |
freq /= 1000; |
|
1062 |
snprintf(buf2, sizeof(buf2), "%03d", freq2); |
|
1063 |
p = buf2 + 2; |
|
1064 |
while (freq2 && (freq2 % 10) == 0) { |
|
1065 |
freq2 /= 10; |
|
1066 |
*(p--) = '\0'; |
|
1141 |
snprintf(buf2, sizeof(buf2), "%03d", freq2); |
|
1142 |
p = buf2 + 2; |
|
1143 |
while (freq2 && (freq2 % 10) == 0) { |
|
1144 |
freq2 /= 10; |
|
1145 |
*(p--) = '\0'; |
|
1146 |
} |
|
1147 |
if (freq2) |
|
1148 |
snprintf(buf, len, "%d.%s%s", freq, buf2, extra); |
|
1149 |
else |
|
1150 |
snprintf(buf, len, "%d%s", freq, extra); |
|
1067 | 1151 |
} |
1068 |
if (freq2) |
|
1069 |
snprintf(buf, len, "%d.%s%s", freq, buf2, extra); |
|
1070 |
else |
|
1071 |
snprintf(buf, len, "%d%s", freq, extra); |
|
1072 | 1152 |
} |
1073 | 1153 | |
1074 | 1154 |
static void |
... | ... | |
1122 | 1202 |
} else if (ln->ln_type == DVB_TYPE_ATSC_C) { |
1123 | 1203 |
idc = &dvb_mux_atsc_c_class; |
1124 | 1204 |
delsys = DVB_SYS_DVBC_ANNEX_B; |
1205 |
} else if (ln->ln_type == DVB_TYPE_CABLECARD) { |
|
1206 |
idc = &dvb_mux_cablecard_class; |
|
1207 |
delsys = DVB_SYS_DVBC_ANNEX_B; |
|
1125 | 1208 |
} else if (ln->ln_type == DVB_TYPE_ISDB_T) { |
1126 | 1209 |
idc = &dvb_mux_isdb_t_class; |
1127 | 1210 |
delsys = DVB_SYS_ISDBT; |
src/input/mpegts/mpegts_network_dvb.c | ||
---|---|---|
360 | 360 |
} |
361 | 361 |
}; |
362 | 362 | |
363 |
const idclass_t dvb_network_cablecard_class = |
|
364 |
{ |
|
365 |
.ic_super = &dvb_network_class, |
|
366 |
.ic_class = "dvb_network_cablecard", |
|
367 |
.ic_caption = N_("CableCARD Network"), |
|
368 |
.ic_properties = (const property_t[]){ |
|
369 |
{} |
|
370 |
} |
|
371 |
}; |
|
372 | ||
363 | 373 |
const idclass_t dvb_network_isdb_t_class = |
364 | 374 |
{ |
365 | 375 |
.ic_super = &dvb_network_class, |
... | ... | |
632 | 642 |
return &dvb_mux_atsc_c_class; |
633 | 643 |
if (idnode_is_instance(&mn->mn_id, &dvb_network_isdb_t_class)) |
634 | 644 |
return &dvb_mux_isdb_t_class; |
645 |
if (idnode_is_instance(&mn->mn_id, &dvb_network_cablecard_class)) |
|
646 |
return &dvb_mux_cablecard_class; |
|
635 | 647 |
if (idnode_is_instance(&mn->mn_id, &dvb_network_isdb_c_class)) |
636 | 648 |
return &dvb_mux_isdb_c_class; |
637 | 649 |
if (idnode_is_instance(&mn->mn_id, &dvb_network_isdb_s_class)) |
... | ... | |
830 | 842 |
dvb_network_create_service |
831 | 843 |
( mpegts_mux_t *mm, uint16_t sid, uint16_t pmt_pid ) |
832 | 844 |
{ |
833 |
return mpegts_service_create1(NULL, mm, sid, pmt_pid, NULL); |
|
845 |
dvb_mux_t *lm = (dvb_mux_t *)mm; |
|
846 |
mpegts_service_t *s; |
|
847 | ||
848 |
s = mpegts_service_create1(NULL, mm, sid, pmt_pid, NULL); |
|
849 | ||
850 |
/* Set service values from mux if CableCARD */ |
|
851 |
if (lm->lm_tuning.dmc_fe_type == DVB_TYPE_CABLECARD) { |
|
852 |
mpegts_network_t *ln = mm->mm_network; |
|
853 |
if (!s->s_dvb_provider && lm->mm_provider_network_name) |
|
854 |
s->s_dvb_provider = strdup(lm->mm_provider_network_name); |
|
855 |
if (!s->s_dvb_provider && ln->mn_provider_network_name) |
|
856 |
s->s_dvb_provider = strdup(ln->mn_provider_network_name); |
|
857 |
if (!s->s_dvb_channel_num) |
|
858 |
s->s_dvb_channel_num = lm->lm_tuning.dmc_fe_vchan.num; |
|
859 |
if (!s->s_dvb_channel_minor && lm->lm_tuning.dmc_fe_vchan.minor) |
|
860 |
s->s_dvb_channel_minor = lm->lm_tuning.dmc_fe_vchan.minor; |
|
861 |
if (!s->s_dvb_svcname && lm->lm_tuning.dmc_fe_vchan.name) |
|
862 |
s->s_dvb_svcname = strdup(lm->lm_tuning.dmc_fe_vchan.name); |
|
863 |
} |
|
864 | ||
865 |
return s; |
|
834 | 866 |
} |
835 | 867 | |
836 | 868 |
static mpegts_mux_t * |
... | ... | |
910 | 942 |
&dvb_network_dvbs_class, |
911 | 943 |
&dvb_network_atsc_t_class, |
912 | 944 |
&dvb_network_atsc_c_class, |
945 |
&dvb_network_cablecard_class, |
|
913 | 946 |
&dvb_network_isdb_t_class, |
914 | 947 |
&dvb_network_isdb_c_class, |
915 | 948 |
&dvb_network_isdb_s_class, |
... | ... | |
924 | 957 |
&dvb_mux_dvbs_class, |
925 | 958 |
&dvb_mux_atsc_t_class, |
926 | 959 |
&dvb_mux_atsc_c_class, |
960 |
&dvb_mux_cablecard_class, |
|
927 | 961 |
&dvb_mux_isdb_t_class, |
928 | 962 |
&dvb_mux_isdb_c_class, |
929 | 963 |
&dvb_mux_isdb_s_class, |
... | ... | |
1003 | 1037 |
return &dvb_network_atsc_t_class; |
1004 | 1038 |
else if (type == DVB_TYPE_ATSC_C) |
1005 | 1039 |
return &dvb_network_atsc_c_class; |
1040 |
else if (type == DVB_TYPE_CABLECARD) |
|
1041 |
return &dvb_network_cablecard_class; |
|
1006 | 1042 |
else if (type == DVB_TYPE_ISDB_T) |
1007 | 1043 |
return &dvb_network_isdb_t_class; |
1008 | 1044 |
else if (type == DVB_TYPE_ISDB_C) |
... | ... | |
1029 | 1065 |
return DVB_TYPE_ATSC_T; |
1030 | 1066 |
else if (idc == &dvb_network_atsc_c_class) |
1031 | 1067 |
return DVB_TYPE_ATSC_C; |
1068 |
else if (idc == &dvb_network_cablecard_class) |
|
1069 |
return DVB_TYPE_CABLECARD; |
|
1032 | 1070 |
else if (idc == &dvb_network_isdb_t_class) |
1033 | 1071 |
return DVB_TYPE_ISDB_T; |
1034 | 1072 |
else if (idc == &dvb_network_isdb_c_class) |
src/input/mpegts/tvhdhomerun/tvhdhomerun.c | ||
---|---|---|
117 | 117 |
htsmsg_add_str(m, NULL, "DVB-C"); |
118 | 118 |
htsmsg_add_str(m, NULL, "ATSC-T"); |
119 | 119 |
htsmsg_add_str(m, NULL, "ATSC-C"); |
120 |
htsmsg_add_str(m, NULL, "CableCARD"); |
|
120 | 121 |
return m; |
121 | 122 |
} |
122 | 123 | |
... | ... | |
318 | 319 |
override_type = "ATSC-T"; |
319 | 320 |
type = dvb_str2type(override_type); |
320 | 321 |
if ( ! ( type == DVB_TYPE_C || type == DVB_TYPE_T || |
321 |
type == DVB_TYPE_ATSC_T || type == DVB_TYPE_ATSC_C ) ) { |
|
322 |
type == DVB_TYPE_ATSC_T || type == DVB_TYPE_ATSC_C || |
|
323 |
type == DVB_TYPE_CABLECARD ) ) { |
|
322 | 324 |
type = DVB_TYPE_C; |
323 | 325 |
} |
324 | 326 |
} |
325 | 327 |
} else { |
326 | 328 |
if (strstr(hd->hd_info.deviceModel, "_atsc")) |
327 | 329 |
type = DVB_TYPE_ATSC_T; |
330 |
if (strstr(hd->hd_info.deviceModel, "_cablecard")) |
|
331 |
type = DVB_TYPE_CABLECARD; |
|
328 | 332 |
} |
329 | 333 | |
330 | 334 |
hd->hd_override_type = strdup(dvb_type2str(type)); |
... | ... | |
455 | 459 |
idclass_register(&tvhdhomerun_frontend_dvbc_class); |
456 | 460 |
idclass_register(&tvhdhomerun_frontend_atsc_t_class); |
457 | 461 |
idclass_register(&tvhdhomerun_frontend_atsc_c_class); |
462 |
idclass_register(&tvhdhomerun_frontend_cablecard_class); |
|
458 | 463 |
TAILQ_INIT(&tvhdhomerun_discoveries); |
459 | 464 |
pthread_mutex_init(&tvhdhomerun_discovery_lock, NULL); |
460 | 465 |
tvh_cond_init(&tvhdhomerun_discovery_cond); |
src/input/mpegts/tvhdhomerun/tvhdhomerun.h | ||
---|---|---|
25 | 25 |
extern const idclass_t tvhdhomerun_frontend_dvbc_class; |
26 | 26 |
extern const idclass_t tvhdhomerun_frontend_atsc_t_class; |
27 | 27 |
extern const idclass_t tvhdhomerun_frontend_atsc_c_class; |
28 |
extern const idclass_t tvhdhomerun_frontend_cablecard_class; |
|
28 | 29 | |
29 | 30 |
void tvhdhomerun_init( void ); |
30 | 31 |
void tvhdhomerun_done( void ); |
src/input/mpegts/tvhdhomerun/tvhdhomerun_frontend.c | ||
---|---|---|
257 | 257 |
tvhdebug(LS_TVHDHOMERUN, "locked"); |
258 | 258 |
hfe->hf_locked = 1; |
259 | 259 | |
260 |
/* Get CableCARD variables */ |
|
261 |
dvb_mux_t *lm = (dvb_mux_t *)mm; |
|
262 |
struct hdhomerun_tuner_vstatus_t tuner_vstatus; |
|
263 |
char *tuner_vstatus_str; |
|
264 |
pthread_mutex_lock(&hfe->hf_hdhomerun_device_mutex); |
|
265 |
res = hdhomerun_device_get_tuner_vstatus(hfe->hf_hdhomerun_tuner, |
|
266 |
&tuner_vstatus_str, &tuner_vstatus); |
|
267 |
pthread_mutex_unlock(&hfe->hf_hdhomerun_device_mutex); |
|
268 |
if (res < 1) |
|
269 |
tvhwarn(LS_TVHDHOMERUN, "tuner_vstatus (%d)", res); |
|
270 |
lm->lm_tuning.dmc_fe_vchan.name = strdup(tuner_vstatus.name); |
|
271 |
sscanf(strstr(tuner_status.channel, ":"), ":%u", &lm->lm_tuning.dmc_fe_freq); |
|
272 | ||
260 | 273 |
/* start input thread */ |
261 | 274 |
tvh_pipe(O_NONBLOCK, &hfe->hf_input_thread_pipe); |
262 | 275 |
pthread_mutex_lock(&hfe->hf_input_thread_mutex); |
... | ... | |
312 | 325 |
char buf[1024]; |
313 | 326 |
int res; |
314 | 327 | |
328 |
if (hfe->hf_type == DVB_TYPE_CABLECARD) |
|
329 |
return; |
|
330 | ||
315 | 331 |
/* a full mux subscription should specificly set the filter */ |
316 | 332 |
if (pid == MPEGTS_FULLMUX_PID) { |
317 | 333 |
tvhdebug(LS_TVHDHOMERUN, "setting PID filter full mux"); |
... | ... | |
417 | 433 |
break; |
418 | 434 |
} |
419 | 435 |
break; |
436 |
case DVB_TYPE_CABLECARD: |
|
437 |
if (!dmc->dmc_fe_vchan.minor) |
|
438 |
snprintf(channel_buf, sizeof(channel_buf), "%u", dmc->dmc_fe_vchan.num); |
|
439 |
else |
|
440 |
snprintf(channel_buf, sizeof(channel_buf), "%u.%u", |
|
441 |
dmc->dmc_fe_vchan.num, |
|
442 |
dmc->dmc_fe_vchan.minor); |
|
443 |
break; |
|
420 | 444 |
default: |
421 | 445 |
snprintf(channel_buf, sizeof(channel_buf), "auto:%u", dmc->dmc_fe_freq); |
422 | 446 |
break; |
... | ... | |
431 | 455 |
tvherror(LS_TVHDHOMERUN, "failed to acquire lockkey: %s", perror); |
432 | 456 |
return SM_CODE_TUNING_FAILED; |
433 | 457 |
} |
434 |
res = hdhomerun_device_set_tuner_channel(hfe->hf_hdhomerun_tuner, channel_buf); |
|
458 |
if (hfe->hf_type == DVB_TYPE_CABLECARD) |
|
459 |
res = hdhomerun_device_set_tuner_vchannel(hfe->hf_hdhomerun_tuner, channel_buf); |
|
460 |
else |
|
461 |
res = hdhomerun_device_set_tuner_channel(hfe->hf_hdhomerun_tuner, channel_buf); |
|
435 | 462 |
pthread_mutex_unlock(&hfe->hf_hdhomerun_device_mutex); |
436 | 463 |
if(res < 1) { |
437 | 464 |
tvherror(LS_TVHDHOMERUN, "failed to tune to %s", channel_buf); |
... | ... | |
463 | 490 |
res = tvhdhomerun_frontend_tune(hfe, mmi); |
464 | 491 | |
465 | 492 |
/* reset the pfilters */ |
466 |
pthread_mutex_lock(&hfe->hf_hdhomerun_device_mutex); |
|
467 |
r = hdhomerun_device_set_tuner_filter(hfe->hf_hdhomerun_tuner, "0x0000"); |
|
468 |
pthread_mutex_unlock(&hfe->hf_hdhomerun_device_mutex); |
|
469 |
if(r < 1) |
|
470 |
tvherror(LS_TVHDHOMERUN, "failed to reset pfilter: %d", r); |
|
493 |
if (hfe->hf_type != DVB_TYPE_CABLECARD) { |
|
494 |
pthread_mutex_lock(&hfe->hf_hdhomerun_device_mutex); |
|
495 |
r = hdhomerun_device_set_tuner_filter(hfe->hf_hdhomerun_tuner, "0x0000"); |
|
496 |
pthread_mutex_unlock(&hfe->hf_hdhomerun_device_mutex); |
|
497 |
if(r < 1) |
|
498 |
tvherror(LS_TVHDHOMERUN, "failed to reset pfilter: %d", r); |
|
499 |
} |
|
471 | 500 | |
472 | 501 |
return res; |
473 | 502 |
} |
... | ... | |
620 | 649 |
} |
621 | 650 |
}; |
622 | 651 | |
652 |
const idclass_t tvhdhomerun_frontend_cablecard_class = |
|
653 |
{ |
|
654 |
.ic_super = &tvhdhomerun_frontend_class, |
|
655 |
.ic_class = "tvhdhomerun_frontend_cablecard", |
|
656 |
.ic_caption = N_("HDHomeRun CableCARD frontend"), |
|
657 |
.ic_properties = (const property_t[]){ |
|
658 |
{} |
|
659 |
} |
|
660 |
}; |
|
661 | ||
623 | 662 |
static mpegts_network_t * |
624 | 663 |
tvhdhomerun_frontend_wizard_network ( tvhdhomerun_frontend_t *hfe ) |
625 | 664 |
{ |
... | ... | |
708 | 747 |
idc = &tvhdhomerun_frontend_atsc_t_class; |
709 | 748 |
else if (type == DVB_TYPE_ATSC_C) |
710 | 749 |
idc = &tvhdhomerun_frontend_atsc_c_class; |
750 |
else if (type == DVB_TYPE_CABLECARD) |
|
751 |
idc = &tvhdhomerun_frontend_cablecard_class; |
|
711 | 752 |
else { |
712 | 753 |
tvherror(LS_TVHDHOMERUN, "unknown FE type %d", type); |
713 | 754 |
return NULL; |