コード例 #1
0
ファイル: tv_grab_dvb.c プロジェクト: milen100/tv_grab_dvb
static void parseEventDescription(void *data, enum ER round) {
    assert(GetDescriptorTag(data) == 0x4D);
    struct descr_short_event *evtdesc = data;
    char evt[256];
    char dsc[256];

    int evtlen = evtdesc->event_name_length;
    if (round == TITLE) {
        if (!evtlen)
            return;
        assert(evtlen < sizeof(evt));
        memcpy(evt, (char *)&evtdesc->data, evtlen);
        evt[evtlen] = '\0';
        printf("\t<title lang=\"%s\">%s</title>\n", xmllang(&evtdesc->lang_code1), xmlify(evt));
        return;
    }

    if (round == SUB_TITLE) {
        int dsclen = evtdesc->data[evtlen];
        assert(dsclen < sizeof(dsc));
        memcpy(dsc, (char *)&evtdesc->data[evtlen+1], dsclen);
        dsc[dsclen] = '\0';

        if (*dsc) {
            char *d = xmlify(dsc);
            if (d && *d)
                printf("\t<sub-title lang=\"%s\">%s</sub-title>\n", xmllang(&evtdesc->lang_code1), d);
        }
    }
} /*}}}*/
コード例 #2
0
ファイル: dvb_epg.cpp プロジェクト: thecrisb/tv_grab_dvb_plus
/*
 * Parse 0x4D Short Event Descriptor
 */
static void parseEventDescription(void *data, enum ER round) {
	assert(GetDescriptorTag(data) == 0x4D);
	struct descr_short_event *evtdesc = CastShortEventDescriptor(data);
	char evt[256];
	char dsc[256];

	int evtlen = evtdesc->event_name_length;
	if (round == TITLE) {
		if (!evtlen)
			return;
		strncpy(evt, (char *) &evtdesc->data, evtlen);
		evt[evtlen] = '\0';
		printf("\t<title lang=\"%s\">%s</title>\n", lookup_language(
				&evtdesc->lang_code1), convert_text(evt));
		return;
	}

	if (round == SUB_TITLE) {
		int dsclen = evtdesc->data[evtlen];
		strncpy(dsc, (char *) &evtdesc->data[evtlen + 1], dsclen);
		dsc[dsclen] = '\0';

		if (*dsc) {
			const char *d = convert_text(dsc);
			if (d && *d)
				printf("\t<sub-title lang=\"%s\">%s</sub-title>\n",
						lookup_language(&evtdesc->lang_code1), d);
		}
	}
}
コード例 #3
0
ファイル: dvb_epg.cpp プロジェクト: thecrisb/tv_grab_dvb_plus
/*
 * Parse 0x54 Content Descriptor
 */
static void parseContentDescription(u_char *data) {
	assert(GetDescriptorTag(data) == 0x54);
	struct descr_content *dc = CastContentDescriptor(data);
	int once[256 / 8 / sizeof(int)] = { 0, };
	u_char *p;
	for (p = (u_char *) (&dc->data); p < (u_char *) (data
			+ dc->descriptor_length); p += NIBBLE_CONTENT_LEN) {
		struct nibble_content *nc = (struct nibble_content *) p;
		int c1 = (nc->content_nibble_level_1 << 4) + nc->content_nibble_level_2;
#ifdef CATEGORY_UNKNOWN
		int c2 = (nc->user_nibble_1 << 4) + nc->user_nibble_2;
#endif
		if (c1 > 0 && !get_bit(once, c1)) {
			set_bit(once, c1);
			const char *c = lookup_description(c1);
			if (c)
				if (c[0])
					printf("\t<category>%s</category>\n", c);
#ifdef CATEGORY_UNKNOWN
			else
				printf("\t<!--category>%s %02X %02X</category-->\n", c + 1, c1, c2);
			else
				printf("\t<!--category>%02X %02X</category-->\n", c1, c2);
#endif
		}
		// This is weird in the uk, they use user but not content, and almost the same values
	}
}
コード例 #4
0
ファイル: tv_grab_dvb.c プロジェクト: milen100/tv_grab_dvb
static void parseComponentDescription(void *data, enum CR round, int *seen) {
    assert(GetDescriptorTag(data) == 0x50);
    struct descr_component *dc = data;
    char buf[256];

    int len = dc->descriptor_length;
    assert(len < sizeof(buf));
    memcpy(buf, (char *)&dc->data, len);
    buf[len] = '\0';

    switch (dc->stream_content) {
    case 0x01: // Video Info
        if (round == VIDEO && !*seen) {
            //if ((dc->component_type-1)&0x08) //HD TV
            //if ((dc->component_type-1)&0x04) //30Hz else 25
            printf("\t<video>\n");
            printf("\t\t<aspect>%s</aspect>\n", lookup(aspect_table, (dc->component_type-1) & 0x03));
            printf("\t</video>\n");
            (*seen)++;
        }
        break;
    case 0x02: // Audio Info
        if (round == AUDIO && !*seen) {
            printf("\t<audio>\n");
            printf("\t\t<stereo>%s</stereo>\n", lookup(audio_table, (dc->component_type)));
            printf("\t</audio>\n");
            (*seen)++;
        }
        if (round == LANGUAGE) {
            if (!*seen)
                printf("\t<language>%s</language>\n", xmllang(&dc->lang_code1));
            else
                printf("\t<!--language>%s</language-->\n", xmllang(&dc->lang_code1));
            (*seen)++;
        }
        break;
    case 0x03: // Teletext Info
        if (round == SUBTITLES) {
            // FIXME: is there a suitable XMLTV output for this?
            // if ((dc->component_type)&0x10) //subtitles
            // if ((dc->component_type)&0x20) //subtitles for hard of hearing
            printf("\t<subtitles type=\"teletext\">\n");
            printf("\t\t<language>%s</language>\n", xmllang(&dc->lang_code1));
            printf("\t</subtitles>\n");
        }
        break;
        // case 0x04: // AC3 info
    }
#if 0
    printf("\t<StreamComponent>\n");
    printf("\t\t<StreamContent>%d</StreamContent>\n", dc->stream_content);
    printf("\t\t<ComponentType>%x</ComponentType>\n", dc->component_type);
    printf("\t\t<ComponentTag>%x</ComponentTag>\n", dc->component_tag);
    printf("\t\t<Length>%d</Length>\n", dc->component_tag, dc->descriptor_length-6);
    printf("\t\t<Language>%s</Language>\n", lang);
    printf("\t\t<Data>%s</Data>\n", buf);
    printf("\t</StreamComponent>\n");
#endif
} /*}}}*/
コード例 #5
0
ファイル: tv_grab_dvb.c プロジェクト: milen100/tv_grab_dvb
/* Check that program has at least a title as is required by xmltv.dtd. {{{ */
static bool validateDescription(void *data, size_t len) {
    void *p;
    for (p = data; p < data + len; p += DESCR_GEN_LEN + GetDescriptorLength(p)) {
        struct descr_gen *desc = p;
        if (GetDescriptorTag(desc) == 0x4D) {
            struct descr_short_event *evtdesc = p;
            // make sure that title isn't empty
            if (evtdesc->event_name_length) return true;
        }
    }
    return false;
} /*}}}*/
コード例 #6
0
ファイル: tv_grab_dvb.c プロジェクト: milen100/tv_grab_dvb
/* Parse 0x4E Extended Event Descriptor. {{{ */
void parseLongEventDescription(void *data) {
    assert(GetDescriptorTag(data) == 0x4E);
    struct descr_extended_event *levt = data;
    char dsc[256];
    bool non_empty = (levt->descriptor_number || levt->last_descriptor_number || levt->length_of_items || levt->data[0]);

    if (non_empty && levt->descriptor_number == 0)
        printf("\t<desc lang=\"%s\">", xmllang(&levt->lang_code1));

    void *p = &levt->data;
    void *data_end = data + DESCR_GEN_LEN + GetDescriptorLength(data);
    while (p < (void *)levt->data + levt->length_of_items) {
        struct item_extended_event *name = p;
        int name_len = name->item_description_length;
        assert(p + ITEM_EXTENDED_EVENT_LEN + name_len < data_end);
        assert(name_len < sizeof(dsc));
        memcpy(dsc, (char *)&name->data, name_len);
        dsc[name_len] = '\0';
        printf("%s: ", xmlify(dsc));

        p += ITEM_EXTENDED_EVENT_LEN + name_len;

        struct item_extended_event *value = p;
        int value_len = value->item_description_length;
        assert(p + ITEM_EXTENDED_EVENT_LEN + value_len < data_end);
        assert(value_len < sizeof(dsc));
        memcpy(dsc, (char *)&value->data, value_len);
        dsc[value_len] = '\0';
        printf("%s; ", xmlify(dsc));

        p += ITEM_EXTENDED_EVENT_LEN + value_len;
    }
    struct item_extended_event *text = p;
    int len = text->item_description_length;
    if (non_empty && len) {
        assert(len < sizeof(dsc));
        memcpy(dsc, (char *)&text->data, len);
        dsc[len] = '\0';
        printf("%s", xmlify(dsc));
    }

    //printf("/%d/%d/%s", levt->descriptor_number, levt->last_descriptor_number, xmlify(dsc));
    if (non_empty && levt->descriptor_number == levt->last_descriptor_number)
        printf("</desc>\n");
} /*}}}*/
コード例 #7
0
ファイル: dvb_epg.cpp プロジェクト: thecrisb/tv_grab_dvb_plus
/*
 * Parse 0x4E Extended Event Descriptor
 */
static void parseLongEventDescription(void *data) {
	assert(GetDescriptorTag(data) == 0x4E);
	struct descr_extended_event *levt = CastExtendedEventDescriptor(data);
	char dsc[256];
	bool non_empty = (levt->descriptor_number || levt->last_descriptor_number
			|| levt->length_of_items || levt->data[0]);

	if (non_empty && levt->descriptor_number == 0)
		printf("\t<desc lang=\"%s\">", lookup_language(&levt->lang_code1));

	u_char *p = (u_char *) &levt->data;
	u_char *data_end = (u_char *) (CastExtendedEventDescriptor(data)
			+ DESCR_GEN_LEN + GetDescriptorLength(data));
	while (p < (u_char *) levt->data + levt->length_of_items) {
		struct item_extended_event *name = (struct item_extended_event *) p;
		int name_len = name->item_description_length;
		assert(p + ITEM_EXTENDED_EVENT_LEN + name_len < data_end);
		strncpy(dsc, (char *) &name->data, name_len);
		dsc[name_len] = '\0';
		printf("%s: ", convert_text(dsc));

		p += ITEM_EXTENDED_EVENT_LEN + name_len;

		struct item_extended_event *value = (struct item_extended_event *) p;
		int value_len = value->item_description_length;
		assert(p + ITEM_EXTENDED_EVENT_LEN + value_len < data_end);
		strncpy(dsc, (char *) &value->data, value_len);
		dsc[value_len] = '\0';
		printf("%s; ", convert_text(dsc));

		p += ITEM_EXTENDED_EVENT_LEN + value_len;
	}
	struct item_extended_event *text = (struct item_extended_event *) p;
	int len = text->item_description_length;
	if (non_empty && len) {
		strncpy(dsc, (char *) &text->data, len);
		dsc[len] = '\0';
		printf("%s", convert_text(dsc));
	}
	//printf("/%d/%d/%s", levt->descriptor_number, levt->last_descriptor_number, convert_text(dsc));
	if (non_empty && levt->descriptor_number == levt->last_descriptor_number)
		printf("</desc>\n");
}
コード例 #8
0
ファイル: tv_grab_dvb.c プロジェクト: milen100/tv_grab_dvb
/* Parse 0x55 Rating Descriptor. {{{ */
void parseRatingDescription(void *data) {
    assert(GetDescriptorTag(data) == 0x55);
    struct descr_parental_rating *pr = data;
    void *p;
    for (p = &pr->data; p < data + pr->descriptor_length; p += PARENTAL_RATING_ITEM_LEN) {
        struct parental_rating_item *pr = p;
        switch (pr->rating) {
        case 0x00: /*undefined*/
            break;
        case 0x01 ... 0x0F:
            printf("\t<rating system=\"dvb\">\n");
            printf("\t\t<value>%d</value>\n", pr->rating + 3);
            printf("\t</rating>\n");
            break;
        case 0x10 ... 0xFF: /*broadcaster defined*/
            break;
        }
    }
} /*}}}*/
コード例 #9
0
ファイル: tv_grab_dvb.c プロジェクト: milen100/tv_grab_dvb
/* See ETSI TS 102 323, section 12 */
void parseContentIdentifierDescription(void *data) {
    assert(GetDescriptorTag(data) == 0x76);
    struct descr_content_identifier *ci = data;
    void *p;
    for (p = &ci->data; p < data + ci->descriptor_length; /* at end */) {
        struct descr_content_identifier_crid *crid = p;
        struct descr_content_identifier_crid_local *crid_data;

        int crid_length = 3;

        char type_buf[32];
        char *type;
        char buf[256];

        type = lookup(crid_type_table, crid->crid_type);
        if (type == NULL)
        {
            type = type_buf;
            sprintf(type_buf, "0x%2x", crid->crid_type);
        }

        switch (crid->crid_location)
        {
        case 0x00: /* Carried explicitly within descriptor */
            crid_data = (descr_content_identifier_crid_local_t *)&crid->crid_ref_data;
            int cridlen = crid_data->crid_length;
            assert(cridlen < sizeof(buf));
            memcpy(buf, (char *)&crid_data->crid_byte, cridlen);
            buf[cridlen] = '\0';

            printf("\t<crid type='%s'>%s</crid>\n", type, xmlify(buf));
            crid_length = 2 + crid_data->crid_length;
            break;
        case 0x01: /* Carried in Content Identifier Table (CIT) */
            break;
        default:
            break;
        }

        p += crid_length;
    }
} /*}}}*/
コード例 #10
0
ファイル: dvb_epg.cpp プロジェクト: thecrisb/tv_grab_dvb_plus
/*
 * Parse Descriptor
 * Tags should be output in this order:
 *
 * 'title', 'sub-title', 'desc', 'credits', 'date', 'category', 'language',
 * 'orig-language', 'length', 'icon', 'url', 'country', 'episode-num',
 * 'video', 'audio', 'previously-shown', 'premiere', 'last-chance',
 * 'new', 'subtitles', 'rating', 'star-rating'
 */
static void parseDescription(u_char *data, size_t len) {
	int round, pds = 0;
	bool notupscaled = true;
        bool audiosubtitle = false;
	for (round = 0; round < 8; round++) {
		int seen = 0; // no title/language/video/audio/subtitles seen in this round
                u_char *p;
		for (p = data; p < (u_char *) (data + len); p += DESCR_GEN_LEN
				+ GetDescriptorLength(p)) {
			struct descr_gen *desc = (struct descr_gen *) p;
			switch (GetDescriptorTag(desc)) {
				case 0:
					break;
				case 0x48: //service_description
					parseServiceDescription(desc);
					break;
				case 0x4D: //short evt desc, [title] [sub-title]
					// there can be multiple language versions of these
					if (round == 0) {
						parseEventDescription(desc, TITLE);
					} else if (round == 1)
						parseEventDescription(desc, SUB_TITLE);
					break;
				case 0x4E: //long evt descriptor [desc]
					if (round == 2)
						parseLongEventDescription(desc);
					break;
				case 0x50: //component desc [language] [video] [audio] [subtitles]
					if (round == 4)
						parseComponentDescription(desc, LANGUAGE, &seen, &notupscaled);
					else if (round == 5)
						parseComponentDescription(desc, VIDEO, &seen, &notupscaled);
					else if (round == 6)
						parseComponentDescription(desc, AUDIO, &seen, &audiosubtitle);
					else if (round == 7)
						parseComponentDescription(desc, SUBTITLES, &seen, &audiosubtitle);
					break;
				case 0x53: // CA Identifier Descriptor
					break;
				case 0x54: // content desc [category]
					if (round == 3)
						parseContentDescription((u_char *) desc);
					break;
				case 0x55: // Parental Rating Descriptor [rating]
					if (round == 7)
						parseRatingDescription((u_char *) desc);
					break;
				case 0x5f: // Private Data Specifier
					pds = parsePrivateDataSpecifier(desc);
					break;
				case 0x64: // Data broadcast desc - Text Desc for Data components
					break;
				case 0x69: // Programm Identification Label
					break;
				case 0x81: // TODO ???
					if (pds == 5) // ARD_ZDF_ORF
						break;
				case 0x82: // VPS (ARD, ZDF, ORF)
					if (pds == 5) // ARD_ZDF_ORF
						// TODO: <programme @vps-start="???">
						break;
				case 0x4F: // Time Shifted Event
				case 0x52: // Stream Identifier Descriptor
				case 0x5E: // Multi Lingual Component Descriptor
				case 0x83: // Logical Channel Descriptor (some kind of news-ticker on ARD-MHP-Data?)
				case 0x84: // Preferred Name List Descriptor
				case 0x85: // Preferred Name Identifier Descriptor
				case 0x86: // Eacem Stream Identifier Descriptor
				default:
					if (round == 0) {
						parseUnknown((u_char *) desc);
					}
			}
		}
	}
}
コード例 #11
0
ファイル: dvb_epg.cpp プロジェクト: thecrisb/tv_grab_dvb_plus
static void parseServiceDescription(void *data) {
	assert(GetDescriptorTag(data) == 0x48);
	struct descr_service *pr = CastServiceDescriptor(data);
	log_message(DEBUG, "got a service descriptor %d", pr->provider_name_length);
}
コード例 #12
0
ファイル: dvb_epg.cpp プロジェクト: thecrisb/tv_grab_dvb_plus
/*
 * Parse 0x5F Private Data Specifier
 */
static int parsePrivateDataSpecifier(void *data) {
	assert(GetDescriptorTag(data) == 0x5F);
	return GetPrivateDataSpecifier(data);
}
コード例 #13
0
ファイル: dvb_epg.cpp プロジェクト: thecrisb/tv_grab_dvb_plus
/*
 * Parse 0x50 Component Descriptor.
 * video is a flag, 1=> output the video information, 0=> output the
 * audio information.  seen is a pointer to a counter to ensure we
 * only output the first one of each (XMLTV can't cope with more than
 * one)
 */
static void parseComponentDescription(void *data, enum CR round, int *seen, bool *testfield) {
	assert(GetDescriptorTag(data) == 0x50);
	struct descr_component *dc = CastComponentDescriptor(data);
	char buf[256];

	int len = dc->descriptor_length;
	strncpy(buf, (char *) &dc->data, len);
	buf[len] = '\0';

	switch (dc->stream_content) {
	case 0x01: // Video Info
        case 0x05: // AVC Video Info
		if (round == VIDEO && !*seen) {
			//if ((dc->component_type-1)&0x08) //HD TV
			//if ((dc->component_type-1)&0x04) //30Hz else 25
			printf("\t<video>\n");
			printf("\t\t<aspect>%s</aspect>\n", lookup_aspect(
					(dc->component_type - 1) & 0x03));
                        if ((dc->component_type-1)>0x07 && *testfield) { //HD TV
                                printf("\t\t<quality>HDTV</quality>\n");
                        }
                        printf("\t</video>\n");
			(*seen)++;
		}
		break;
	case 0x02: // Audio Info
        case 0x06: { // AVC Audio Info
            std::string audioinfo = lookup_audio(dc->component_type);
             if (round == SUBTITLES && audioinfo.compare("audio-subtitle") == 0 && *seen < 4 ) {
                    if (testfield && *seen != 2) {
        		printf("\t<subtitles type=\"audio-described\">\n");
                	printf("\t\t<language>%s</language>\n", lookup_language(&dc->lang_code1));
                        printf("\t</subtitles>\n");
                (*seen)+=4;
                }
               }
		if (round == AUDIO && !*seen && audioinfo.compare("audio-subtitle") !=0) {
			printf("\t<audio>\n");
			printf("\t\t<stereo>%s</stereo>\n",
					lookup_audio(dc->component_type));
			printf("\t</audio>\n");
			(*seen)++;
		}
		if (round == LANGUAGE) {
			if (!*seen) {
				printf("\t<language>%s</language>\n", lookup_language(
						&dc->lang_code1));
			} else {
				//printf("\t<!--language>%s</language-->\n", lookup_language(&dc->lang_code1));
			}
			(*seen)++;
		}
                }
                break;
	case 0x03: // Teletext Info
            if (round == LANGUAGE){ // need this BEFORE VIDEO runs
                if ((dc->component_type)&0x40) {
			*testfield=false;
			}
            }
            if (round == SUBTITLES) {
            switch (dc->component_type) {
            case 0x01:
            case 0x10:
            case 0x11:
            case 0x12:
            case 0x13:
            case 0x14:
            case 0x15:
            case 0x20:
            case 0x21:
            case 0x22:
            case 0x23:
            case 0x24:
            case 0x25: 
                if (testfield && *seen != 2 && *seen != 3 && *seen != 6 && *seen != 7) {
		printf("\t<subtitles type=\"teletext\">\n");
		printf("\t\t<language>%s</language>\n", lookup_language(&dc->lang_code1));
		printf("\t</subtitles>\n");
                (*seen)+=2;
                }
            break;
            case 0x30:
            case 0x31:
                if (testfield && *seen != 1 && *seen != 3 && *seen != 5 && *seen != 7) {
		printf("\t<subtitles type=\"deaf-signed\">\n");
		printf("\t\t<language>%s</language>\n", lookup_language(&dc->lang_code1));
		printf("\t</subtitles>\n");
                (*seen)++;
                }
            }    
                // FIXME: is there a suitable XMLTV output for this?
		// if ((dc->component_type)&0x10) //subtitles
		// if ((dc->component_type)&0x20) //subtitles for hard of hearing
		//printf("\t<subtitles type=\"teletext\">\n");
		//printf("\t\t<language>%s</language>\n", lookup_language(&dc->lang_code1));
		//printf("\t</subtitles>\n");
            }
		//break;
		// case 0x04: // AC3 info
            break;
        }
}