Ejemplo n.º 1
0
static void parse_vdr_par_string(const char *vdr_par_str, dvb_channel_t *ptr)
{
    //FIXME: There is more information in this parameter string, especially related
    // to non-DVB-S reception.
    if (vdr_par_str[0]) {
        const char *vdr_par = &vdr_par_str[0];
        while (vdr_par && *vdr_par) {
            switch (mp_toupper(*vdr_par)) {
            case 'H':
                ptr->pol = 'H';
                vdr_par++;
                break;
            case 'V':
                ptr->pol = 'V';
                vdr_par++;
                break;
            case 'S':
                vdr_par++;
                if (*vdr_par == '1') {
                    ptr->is_dvb_s2 = true;
                } else {
                    ptr->is_dvb_s2 = false;
                }
                vdr_par++;
                break;
            case 'P':
                vdr_par++;
                char *endptr = NULL;
                errno = 0;
                int n = strtol(vdr_par, &endptr, 10);
                if (!errno && endptr != vdr_par) {
                    ptr->stream_id = n;
                    vdr_par = endptr;
                }
                break;
            case 'I':
                vdr_par++;
                if (*vdr_par == '1') {
                    ptr->inv = INVERSION_ON;
                } else {
                    ptr->inv = INVERSION_OFF;
                }
                vdr_par++;
                break;
            default:
                vdr_par++;
            }
        }
    }
}
Ejemplo n.º 2
0
static dvb_channels_list *dvb_get_channels(struct mp_log *log, char *filename, int type)
{
        dvb_channels_list  *list;
        FILE *f;
        char line[CHANNEL_LINE_LEN], *colon;

        if (!filename)
            return NULL;

        int fields, cnt, pcnt, k;
        int has8192, has0;
        dvb_channel_t *ptr, *tmp, chn;
        char tmp_lcr[256], tmp_hier[256], inv[256], bw[256], cr[256], mod[256], transm[256], gi[256], vpid_str[256], apid_str[256];
        const char *cbl_conf = "%d:%255[^:]:%d:%255[^:]:%255[^:]:%255[^:]:%255[^:]\n";
        const char *sat_conf = "%d:%c:%d:%d:%255[^:]:%255[^:]\n";
        const char *ter_conf = "%d:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]\n";
        const char *atsc_conf = "%d:%255[^:]:%255[^:]:%255[^:]\n";

        mp_verbose(log, "CONFIG_READ FILE: %s, type: %d\n", filename, type);
        if((f=fopen(filename, "r"))==NULL)
        {
                mp_fatal(log, "CAN'T READ CONFIG FILE %s\n", filename);
                return NULL;
        }

        list = malloc(sizeof(dvb_channels_list));
        if(list == NULL)
        {
                fclose(f);
                mp_verbose(log, "DVB_GET_CHANNELS: couldn't malloc enough memory\n");
                return NULL;
        }

        ptr = &chn;
        list->NUM_CHANNELS = 0;
        list->channels = NULL;
        while(! feof(f))
        {
                if( fgets(line, CHANNEL_LINE_LEN, f) == NULL )
                        continue;

                if((line[0] == '#') || (strlen(line) == 0))
                        continue;

                colon = strchr(line, ':');
                if(colon)
                {
                        k = colon - line;
                        if(!k)
                                continue;
                        ptr->name = malloc(k+1);
                        if(! ptr->name)
                                continue;
                        av_strlcpy(ptr->name, line, k+1);
                }
                else
                        continue;
                k++;
                apid_str[0] = vpid_str[0] = 0;
                ptr->pids_cnt = 0;
                ptr->freq = 0;
                if(type == TUNER_TER)
                {
                        fields = sscanf(&line[k], ter_conf,
                                &ptr->freq, inv, bw, cr, tmp_lcr, mod,
                                transm, gi, tmp_hier, vpid_str, apid_str);
                        mp_verbose(log, "TER, NUM: %d, NUM_FIELDS: %d, NAME: %s, FREQ: %d",
                                list->NUM_CHANNELS, fields, ptr->name, ptr->freq);
                }
                else if(type == TUNER_CBL)
                {
                        fields = sscanf(&line[k], cbl_conf,
                                &ptr->freq, inv, &ptr->srate,
                                cr, mod, vpid_str, apid_str);
                        mp_verbose(log, "CBL, NUM: %d, NUM_FIELDS: %d, NAME: %s, FREQ: %d, SRATE: %d",
                                list->NUM_CHANNELS, fields, ptr->name, ptr->freq, ptr->srate);
                }
#ifdef DVB_ATSC
                else if(type == TUNER_ATSC)
                {
                        fields = sscanf(&line[k], atsc_conf,
                                 &ptr->freq, mod, vpid_str, apid_str);
                        mp_verbose(log, "ATSC, NUM: %d, NUM_FIELDS: %d, NAME: %s, FREQ: %d\n",
                                list->NUM_CHANNELS, fields, ptr->name, ptr->freq);
                }
#endif
                else //SATELLITE
                {
                        fields = sscanf(&line[k], sat_conf,
                                &ptr->freq, &ptr->pol, &ptr->diseqc, &ptr->srate, vpid_str, apid_str);
                        ptr->pol = mp_toupper(ptr->pol);
                        ptr->freq *=  1000UL;
                        ptr->srate *=  1000UL;
                        ptr->tone = -1;
                        ptr->inv = INVERSION_AUTO;
                        ptr->cr = FEC_AUTO;
                        if((ptr->diseqc > 4) || (ptr->diseqc < 0))
                            continue;
                        if(ptr->diseqc > 0)
                            ptr->diseqc--;
                        mp_verbose(log, "SAT, NUM: %d, NUM_FIELDS: %d, NAME: %s, FREQ: %d, SRATE: %d, POL: %c, DISEQC: %d",
                                list->NUM_CHANNELS, fields, ptr->name, ptr->freq, ptr->srate, ptr->pol, ptr->diseqc);
                }

                if(vpid_str[0])
                {
                        pcnt = sscanf(vpid_str, "%d+%d+%d+%d+%d+%d+%d", &ptr->pids[0], &ptr->pids[1], &ptr->pids[2], &ptr->pids[3],
                                &ptr->pids[4], &ptr->pids[5], &ptr->pids[6]);
                        if(pcnt > 0)
                        {
                                ptr->pids_cnt = pcnt;
                                fields++;
                        }
                }

                if(apid_str[0])
                {
                        cnt = ptr->pids_cnt;
                        pcnt = sscanf(apid_str, "%d+%d+%d+%d+%d+%d+%d+%d", &ptr->pids[cnt], &ptr->pids[cnt+1], &ptr->pids[cnt+2],
                                &ptr->pids[cnt+3], &ptr->pids[cnt+4], &ptr->pids[cnt+5], &ptr->pids[cnt+6], &ptr->pids[cnt+7]);
                        if(pcnt > 0)
                        {
                                ptr->pids_cnt += pcnt;
                                fields++;
                        }
                }

                if((fields < 2) || (ptr->pids_cnt <= 0) || (ptr->freq == 0) || (strlen(ptr->name) == 0))
                        continue;

                has8192 = has0 = 0;
                for(cnt = 0; cnt < ptr->pids_cnt; cnt++)
                {
                        if(ptr->pids[cnt] == 8192)
                                has8192 = 1;
                        if(ptr->pids[cnt] == 0)
                                has0 = 1;
                }
                if(has8192)
                {
                        ptr->pids[0] = 8192;
                        ptr->pids_cnt = 1;
                }
                else if(! has0)
                {
                        ptr->pids[ptr->pids_cnt] = 0;   //PID 0 is the PAT
                        ptr->pids_cnt++;
                }
                mp_verbose(log, " PIDS: ");
                for(cnt = 0; cnt < ptr->pids_cnt; cnt++)
                        mp_verbose(log, " %d ", ptr->pids[cnt]);
                mp_verbose(log, "\n");

                if((type == TUNER_TER) || (type == TUNER_CBL))
                {
                        if(! strcmp(inv, "INVERSION_ON"))
                                ptr->inv = INVERSION_ON;
                        else if(! strcmp(inv, "INVERSION_OFF"))
                                ptr->inv = INVERSION_OFF;
                        else
                                ptr->inv = INVERSION_AUTO;


                        if(! strcmp(cr, "FEC_1_2"))
                                ptr->cr =FEC_1_2;
                        else if(! strcmp(cr, "FEC_2_3"))
                                ptr->cr =FEC_2_3;
                        else if(! strcmp(cr, "FEC_3_4"))
                                ptr->cr =FEC_3_4;
                        else if(! strcmp(cr, "FEC_4_5"))
                                ptr->cr =FEC_4_5;
                        else if(! strcmp(cr, "FEC_6_7"))
                                ptr->cr =FEC_6_7;
                        else if(! strcmp(cr, "FEC_8_9"))
                                ptr->cr =FEC_8_9;
                        else if(! strcmp(cr, "FEC_5_6"))
                                ptr->cr =FEC_5_6;
                        else if(! strcmp(cr, "FEC_7_8"))
                                ptr->cr =FEC_7_8;
                        else if(! strcmp(cr, "FEC_NONE"))
                                ptr->cr =FEC_NONE;
                        else ptr->cr =FEC_AUTO;
                }


                if((type == TUNER_TER) || (type == TUNER_CBL) || (type == TUNER_ATSC))
                {
                        if(! strcmp(mod, "QAM_128"))
                                ptr->mod = QAM_128;
                        else if(! strcmp(mod, "QAM_256"))
                                ptr->mod = QAM_256;
                        else if(! strcmp(mod, "QAM_64"))
                                ptr->mod = QAM_64;
                        else if(! strcmp(mod, "QAM_32"))
                                ptr->mod = QAM_32;
                        else if(! strcmp(mod, "QAM_16"))
                                ptr->mod = QAM_16;
#ifdef DVB_ATSC
                        else if(! strcmp(mod, "VSB_8") || ! strcmp(mod, "8VSB"))
                                ptr->mod = VSB_8;
                        else if(! strcmp(mod, "VSB_16") || !strcmp(mod, "16VSB"))
                                ptr->mod = VSB_16;
                        else if(! strcmp(mod, "QAM_AUTO"))
                                ptr->mod = QAM_AUTO;

#endif
                }

                if(type == TUNER_TER)
                {
                        if(! strcmp(bw, "BANDWIDTH_6_MHZ"))
                                ptr->bw = BANDWIDTH_6_MHZ;
                        else if(! strcmp(bw, "BANDWIDTH_7_MHZ"))
                                ptr->bw = BANDWIDTH_7_MHZ;
                        else if(! strcmp(bw, "BANDWIDTH_8_MHZ"))
                                ptr->bw = BANDWIDTH_8_MHZ;


                        if(! strcmp(transm, "TRANSMISSION_MODE_2K"))
                                ptr->trans = TRANSMISSION_MODE_2K;
                        else if(! strcmp(transm, "TRANSMISSION_MODE_8K"))
                                ptr->trans = TRANSMISSION_MODE_8K;
                        else if(! strcmp(transm, "TRANSMISSION_MODE_AUTO"))
                                ptr->trans = TRANSMISSION_MODE_AUTO;

                        if(! strcmp(gi, "GUARD_INTERVAL_1_32"))
                                ptr->gi = GUARD_INTERVAL_1_32;
                        else if(! strcmp(gi, "GUARD_INTERVAL_1_16"))
                                ptr->gi = GUARD_INTERVAL_1_16;
                        else if(! strcmp(gi, "GUARD_INTERVAL_1_8"))
                                ptr->gi = GUARD_INTERVAL_1_8;
                        else if(! strcmp(gi, "GUARD_INTERVAL_1_4"))
                                ptr->gi = GUARD_INTERVAL_1_4;
                        else ptr->gi = GUARD_INTERVAL_AUTO;

                        if(! strcmp(tmp_lcr, "FEC_1_2"))
                                ptr->cr_lp =FEC_1_2;
                        else if(! strcmp(tmp_lcr, "FEC_2_3"))
                                ptr->cr_lp =FEC_2_3;
                        else if(! strcmp(tmp_lcr, "FEC_3_4"))
                                ptr->cr_lp =FEC_3_4;
                        else if(! strcmp(tmp_lcr, "FEC_4_5"))
                                ptr->cr_lp =FEC_4_5;
                        else if(! strcmp(tmp_lcr, "FEC_6_7"))
                                ptr->cr_lp =FEC_6_7;
                        else if(! strcmp(tmp_lcr, "FEC_8_9"))
                                ptr->cr_lp =FEC_8_9;
                        else if(! strcmp(tmp_lcr, "FEC_5_6"))
                                ptr->cr_lp =FEC_5_6;
                        else if(! strcmp(tmp_lcr, "FEC_7_8"))
                                ptr->cr_lp =FEC_7_8;
                        else if(! strcmp(tmp_lcr, "FEC_NONE"))
                                ptr->cr_lp =FEC_NONE;
                        else ptr->cr_lp =FEC_AUTO;


                        if(! strcmp(tmp_hier, "HIERARCHY_1"))
                                ptr->hier = HIERARCHY_1;
                        else if(! strcmp(tmp_hier, "HIERARCHY_2"))
                                ptr->hier = HIERARCHY_2;
                        else if(! strcmp(tmp_hier, "HIERARCHY_4"))
                                ptr->hier = HIERARCHY_4;
                        else if(! strcmp(tmp_hier, "HIERARCHY_AUTO"))
                                ptr->hier = HIERARCHY_AUTO;
                        else    ptr->hier = HIERARCHY_NONE;
                }

                tmp = realloc(list->channels, sizeof(dvb_channel_t) * (list->NUM_CHANNELS + 1));
                if(tmp == NULL)
                        break;

                list->channels = tmp;
                memcpy(&(list->channels[list->NUM_CHANNELS]), ptr, sizeof(dvb_channel_t));
                list->NUM_CHANNELS++;
                if(sizeof(dvb_channel_t) * list->NUM_CHANNELS >= 1024*1024)
                {
                        mp_verbose(log, "dvbin.c, > 1MB allocated for channels struct, dropping the rest of the file\r\n");
                        break;
                }
        }

        fclose(f);
        if(list->NUM_CHANNELS == 0)
        {
                free(list->channels);
                free(list);
                return NULL;
        }

        list->current = 0;
        return list;
}
Ejemplo n.º 3
0
static dvb_channels_list *dvb_get_channels(struct mp_log *log,
                                           int cfg_full_transponder,
                                           char *filename,
                                           int type)
{
    dvb_channels_list *list;
    FILE *f;
    char line[CHANNEL_LINE_LEN], *colon;

    if (!filename)
        return NULL;

    int fields, cnt, k;
    int has8192, has0;
    dvb_channel_t *ptr, *tmp, chn;
    char tmp_lcr[256], tmp_hier[256], inv[256], bw[256], cr[256], mod[256],
         transm[256], gi[256], vpid_str[256], apid_str[256], tpid_str[256],
         vdr_par_str[256], vdr_loc_str[256];
    const char *cbl_conf =
        "%d:%255[^:]:%d:%255[^:]:%255[^:]:%255[^:]:%255[^:]\n";
    const char *sat_conf = "%d:%c:%d:%d:%255[^:]:%255[^:]\n";
    const char *ter_conf =
        "%d:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]\n";
    const char *atsc_conf = "%d:%255[^:]:%255[^:]:%255[^:]\n";

    const char *vdr_conf =
        "%d:%255[^:]:%255[^:]:%d:%255[^:]:%255[^:]:%255[^:]:%*255[^:]:%d:%*d:%*d:%*d\n%n";

    mp_verbose(log, "CONFIG_READ FILE: %s, type: %d\n", filename, type);
    if ((f = fopen(filename, "r")) == NULL) {
        mp_fatal(log, "CAN'T READ CONFIG FILE %s\n", filename);
        return NULL;
    }

    list = malloc(sizeof(dvb_channels_list));
    if (list == NULL) {
        fclose(f);
        mp_verbose(log, "DVB_GET_CHANNELS: couldn't malloc enough memory\n");
        return NULL;
    }

    ptr = &chn;
    list->NUM_CHANNELS = 0;
    list->channels = NULL;
    while (!feof(f)) {
        if (fgets(line, CHANNEL_LINE_LEN, f) == NULL)
            continue;

        if ((line[0] == '#') || (strlen(line) == 0))
            continue;

        colon = strchr(line, ':');
        if (colon) {
            k = colon - line;
            if (!k)
                continue;
            // In some modern VDR-style configs, channel name also has bouquet after ;.
            // Parse that off, we ignore it.
            char *bouquet_sep = strchr(line, ';');
            int channel_name_length = k;
            if (bouquet_sep && bouquet_sep < colon)
                channel_name_length = bouquet_sep - line;
            ptr->name = malloc(channel_name_length + 1);
            if (!ptr->name)
                continue;
            av_strlcpy(ptr->name, line, channel_name_length + 1);
        } else {
            continue;
        }
        k++;
        vpid_str[0] = apid_str[0] = tpid_str[0] = 0;
        vdr_loc_str[0] = vdr_par_str[0] = 0;
        ptr->pids_cnt = 0;
        ptr->freq = 0;
        ptr->is_dvb_s2 = false;
        ptr->service_id = -1;
        ptr->stream_id = NO_STREAM_ID_FILTER;
        ptr->inv = INVERSION_AUTO;

        // Check if VDR-type channels.conf-line - then full line is consumed by the scan.
        int num_chars = 0;
        fields = sscanf(&line[k], vdr_conf,
                        &ptr->freq, vdr_par_str, vdr_loc_str, &ptr->srate,
                        vpid_str, apid_str, tpid_str, &ptr->service_id,
                        &num_chars);

        if (num_chars == strlen(&line[k])) {
            // It's a VDR-style config line.
            parse_vdr_par_string(vdr_par_str, ptr);
            // We still need the special SAT-handling here.
            if (type != TUNER_TER && type != TUNER_CBL && type != TUNER_ATSC) {
                ptr->freq *=  1000UL;
                ptr->srate *=  1000UL;
                ptr->tone = -1;
                ptr->inv = INVERSION_AUTO;
                ptr->cr = FEC_AUTO;

                if (vdr_loc_str[0]) {
                    // In older vdr config format, this field contained the DISEQc information.
                    // If it is numeric, assume that's it.
                    int diseqc_info = 0;
                    int valid_digits = 0;
                    if (sscanf(vdr_loc_str, "%d%n", &diseqc_info,
                               &valid_digits) == 1)
                    {
                        if (valid_digits == strlen(vdr_loc_str)) {
                            ptr->diseqc = diseqc_info;
                            if ((ptr->diseqc > 4) || (ptr->diseqc < 0))
                                continue;
                            if (ptr->diseqc > 0)
                                ptr->diseqc--;
                        }
                    }
                }

                mp_verbose(log, "SAT, NUM: %d, NUM_FIELDS: %d, NAME: %s, "
                           "FREQ: %d, SRATE: %d, POL: %c, DISEQC: %d, S2: %s, "
                           "StreamID: %d, SID: %d", list->NUM_CHANNELS,
                           fields, ptr->name, ptr->freq, ptr->srate, ptr->pol,
                           ptr->diseqc, ptr->is_dvb_s2 ? "yes" : "no",
                           ptr->stream_id, ptr->service_id);
            } else {
                mp_verbose(log, "VDR, NUM: %d, NUM_FIELDS: %d, NAME: %s, "
                           "FREQ: %d, SRATE: %d", list->NUM_CHANNELS, fields,
                           ptr->name, ptr->freq, ptr->srate);
            }
        } else if (type == TUNER_TER) {
            fields = sscanf(&line[k], ter_conf,
                            &ptr->freq, inv, bw, cr, tmp_lcr, mod,
                            transm, gi, tmp_hier, vpid_str, apid_str);
            mp_verbose(log, "TER, NUM: %d, NUM_FIELDS: %d, NAME: %s, FREQ: %d",
                       list->NUM_CHANNELS, fields, ptr->name, ptr->freq);
        } else if (type == TUNER_CBL) {
            fields = sscanf(&line[k], cbl_conf,
                            &ptr->freq, inv, &ptr->srate,
                            cr, mod, vpid_str, apid_str);
            mp_verbose(log, "CBL, NUM: %d, NUM_FIELDS: %d, NAME: %s, FREQ: %d, "
                       "SRATE: %d", list->NUM_CHANNELS, fields, ptr->name,
                       ptr->freq, ptr->srate);
        }
#ifdef DVB_ATSC
        else if (type == TUNER_ATSC) {
            fields = sscanf(&line[k], atsc_conf,
                            &ptr->freq, mod, vpid_str, apid_str);
            mp_verbose(log, "ATSC, NUM: %d, NUM_FIELDS: %d, NAME: %s, FREQ: %d\n",
                       list->NUM_CHANNELS, fields, ptr->name, ptr->freq);
        }
#endif
        else {       //SATELLITE
            fields = sscanf(&line[k], sat_conf,
                            &ptr->freq, &ptr->pol, &ptr->diseqc, &ptr->srate,
                            vpid_str,
                            apid_str);
            ptr->pol = mp_toupper(ptr->pol);
            ptr->freq *=  1000UL;
            ptr->srate *=  1000UL;
            ptr->tone = -1;
            ptr->inv = INVERSION_AUTO;
            ptr->cr = FEC_AUTO;
            if ((ptr->diseqc > 4) || (ptr->diseqc < 0))
                continue;
            if (ptr->diseqc > 0)
                ptr->diseqc--;
            mp_verbose(log, "SAT, NUM: %d, NUM_FIELDS: %d, NAME: %s, FREQ: %d, "
                       "SRATE: %d, POL: %c, DISEQC: %d",
                       list->NUM_CHANNELS, fields, ptr->name, ptr->freq,
                       ptr->srate, ptr->pol, ptr->diseqc);
        }

        if (parse_pid_string(log, vpid_str, ptr))
            fields++;
        if (parse_pid_string(log, apid_str, ptr))
            fields++;
                 /* If we do not know the service_id, PMT can not be extracted.
                    Teletext decoding will fail without PMT. */
        if (ptr->service_id != -1) {
            if (parse_pid_string(log, tpid_str, ptr))
                fields++;
        }


        if ((fields < 2) || (ptr->pids_cnt <= 0) || (ptr->freq == 0) ||
            (strlen(ptr->name) == 0))
            continue;

        /* Add some PIDs which are mandatory in DVB,
         * and contain human-readable helpful data. */

        /* This is the STD, the service description table.
         * It contains service names and such, ffmpeg decodes it. */
        ptr->pids[ptr->pids_cnt] = 0x0011;
        ptr->pids_cnt++;

        /* This is the EIT, which contains EPG data.
         * ffmpeg can not decode it (yet), but e.g. VLC
         * shows what was recorded. */
        ptr->pids[ptr->pids_cnt] = 0x0012;
        ptr->pids_cnt++;

        if (ptr->service_id != -1) {
            /* We have the PMT-PID in addition.
               This will be found later, when we tune to the channel.
               Push back here to create the additional demux. */
            ptr->pids[ptr->pids_cnt] = -1;       // Placeholder.
            ptr->pids_cnt++;
        }

        has8192 = has0 = 0;
        for (cnt = 0; cnt < ptr->pids_cnt; cnt++) {
            if (ptr->pids[cnt] == 8192)
                has8192 = 1;
            if (ptr->pids[cnt] == 0)
                has0 = 1;
        }

        /* 8192 is the pseudo-PID for full TP dump,
           enforce that if requested. */
        if (!has8192 && cfg_full_transponder)
            has8192 = 1;
        if (has8192) {
            ptr->pids[0] = 8192;
            ptr->pids_cnt = 1;
        } else if (!has0) {
            ptr->pids[ptr->pids_cnt] = 0;               //PID 0 is the PAT
            ptr->pids_cnt++;
        }

        mp_verbose(log, " PIDS: ");
        for (cnt = 0; cnt < ptr->pids_cnt; cnt++)
            mp_verbose(log, " %d ", ptr->pids[cnt]);
        mp_verbose(log, "\n");

        if ((type == TUNER_TER) || (type == TUNER_CBL)) {
            if (!strcmp(inv, "INVERSION_ON")) {
                ptr->inv = INVERSION_ON;
            } else if (!strcmp(inv, "INVERSION_OFF")) {
                ptr->inv = INVERSION_OFF;
            } else {
                ptr->inv = INVERSION_AUTO;
            }


            if (!strcmp(cr, "FEC_1_2")) {
                ptr->cr = FEC_1_2;
            } else if (!strcmp(cr, "FEC_2_3")) {
                ptr->cr = FEC_2_3;
            } else if (!strcmp(cr, "FEC_3_4")) {
                ptr->cr = FEC_3_4;
            } else if (!strcmp(cr, "FEC_4_5")) {
                ptr->cr = FEC_4_5;
            } else if (!strcmp(cr, "FEC_6_7")) {
                ptr->cr = FEC_6_7;
            } else if (!strcmp(cr, "FEC_8_9")) {
                ptr->cr = FEC_8_9;
            } else if (!strcmp(cr, "FEC_5_6")) {
                ptr->cr = FEC_5_6;
            } else if (!strcmp(cr, "FEC_7_8")) {
                ptr->cr = FEC_7_8;
            } else if (!strcmp(cr, "FEC_NONE")) {
                ptr->cr = FEC_NONE;
            } else {
                ptr->cr = FEC_AUTO;
            }
        }


        if (type == TUNER_TER || type == TUNER_CBL || type == TUNER_ATSC) {
            if (!strcmp(mod, "QAM_128")) {
                ptr->mod = QAM_128;
            } else if (!strcmp(mod, "QAM_256")) {
                ptr->mod = QAM_256;
            } else if (!strcmp(mod, "QAM_64")) {
                ptr->mod = QAM_64;
            } else if (!strcmp(mod, "QAM_32")) {
                ptr->mod = QAM_32;
            } else if (!strcmp(mod, "QAM_16")) {
                ptr->mod = QAM_16;
#ifdef DVB_ATSC
            } else if (!strcmp(mod, "VSB_8") || !strcmp(mod, "8VSB")) {
                ptr->mod = VSB_8;
            } else if (!strcmp(mod, "VSB_16") || !strcmp(mod, "16VSB")) {
                ptr->mod = VSB_16;
            } else if (!strcmp(mod, "QAM_AUTO")) {
                ptr->mod = QAM_AUTO;
            }

#endif
        }

        if (type == TUNER_TER) {
            if (!strcmp(bw, "BANDWIDTH_6_MHZ")) {
                ptr->bw = BANDWIDTH_6_MHZ;
            } else if (!strcmp(bw, "BANDWIDTH_7_MHZ")) {
                ptr->bw = BANDWIDTH_7_MHZ;
            } else if (!strcmp(bw, "BANDWIDTH_8_MHZ")) {
                ptr->bw = BANDWIDTH_8_MHZ;
            }


            if (!strcmp(transm, "TRANSMISSION_MODE_2K")) {
                ptr->trans = TRANSMISSION_MODE_2K;
            } else if (!strcmp(transm, "TRANSMISSION_MODE_8K")) {
                ptr->trans = TRANSMISSION_MODE_8K;
            } else if (!strcmp(transm, "TRANSMISSION_MODE_AUTO")) {
                ptr->trans = TRANSMISSION_MODE_AUTO;
            }

            if (!strcmp(gi, "GUARD_INTERVAL_1_32")) {
                ptr->gi = GUARD_INTERVAL_1_32;
            } else if (!strcmp(gi, "GUARD_INTERVAL_1_16")) {
                ptr->gi = GUARD_INTERVAL_1_16;
            } else if (!strcmp(gi, "GUARD_INTERVAL_1_8")) {
                ptr->gi = GUARD_INTERVAL_1_8;
            } else if (!strcmp(gi, "GUARD_INTERVAL_1_4")) {
                ptr->gi = GUARD_INTERVAL_1_4;
            } else {
                ptr->gi = GUARD_INTERVAL_AUTO;
            }

            if (!strcmp(tmp_lcr, "FEC_1_2")) {
                ptr->cr_lp = FEC_1_2;
            } else if (!strcmp(tmp_lcr, "FEC_2_3")) {
                ptr->cr_lp = FEC_2_3;
            } else if (!strcmp(tmp_lcr, "FEC_3_4")) {
                ptr->cr_lp = FEC_3_4;
            } else if (!strcmp(tmp_lcr, "FEC_4_5")) {
                ptr->cr_lp = FEC_4_5;
            } else if (!strcmp(tmp_lcr, "FEC_6_7")) {
                ptr->cr_lp = FEC_6_7;
            } else if (!strcmp(tmp_lcr, "FEC_8_9")) {
                ptr->cr_lp = FEC_8_9;
            } else if (!strcmp(tmp_lcr, "FEC_5_6")) {
                ptr->cr_lp = FEC_5_6;
            } else if (!strcmp(tmp_lcr, "FEC_7_8")) {
                ptr->cr_lp = FEC_7_8;
            } else if (!strcmp(tmp_lcr, "FEC_NONE")) {
                ptr->cr_lp = FEC_NONE;
            } else {
                ptr->cr_lp = FEC_AUTO;
            }


            if (!strcmp(tmp_hier, "HIERARCHY_1")) {
                ptr->hier = HIERARCHY_1;
            } else if (!strcmp(tmp_hier, "HIERARCHY_2")) {
                ptr->hier = HIERARCHY_2;
            } else if (!strcmp(tmp_hier, "HIERARCHY_4")) {
                ptr->hier = HIERARCHY_4;
            } else if (!strcmp(tmp_hier, "HIERARCHY_AUTO")) {
                ptr->hier = HIERARCHY_AUTO;
            } else {
                ptr->hier = HIERARCHY_NONE;
            }
        }

        tmp = realloc(list->channels, sizeof(dvb_channel_t) *
                      (list->NUM_CHANNELS + 1));
        if (tmp == NULL)
            break;

        list->channels = tmp;
        memcpy(&(list->channels[list->NUM_CHANNELS]), ptr, sizeof(dvb_channel_t));
        list->NUM_CHANNELS++;
        if (sizeof(dvb_channel_t) * list->NUM_CHANNELS >= 1024 * 1024) {
            mp_verbose(log, "dvbin.c, > 1MB allocated for channels struct, "
                            "dropping the rest of the file\n");
            break;
        }
    }

    fclose(f);
    if (list->NUM_CHANNELS == 0) {
        free(list->channels);
        free(list);
        return NULL;
    }

    list->current = 0;
    return list;
}